返回简单类型的泛型方法

时间:2012-06-06 20:00:20

标签: c# generics

确定, 我有一些我不太喜欢的代码。鉴于我没有写它而只是继承它,我发现我可以将它清理一下。基本上,我们有一个NHibernate持久设置的对象。我不会厌倦了实现细节,只是说它包含一个字典,其中包含我们在数据库中保存的实际值。

我们的典型属性实现如下:

public string MyDumbProperty
{
get { return GetStringValue("MyDumbProperty", string.Empty); }
set { SetValue("MyDumbProperty", value);}
}

现在,从上面的实现可能很明显,我们为每个返回的类型(字符串,整数,长整数,浮点数等)都有单独的Getxxxx方法,第二个参数是默认值。我想要的是能够做如下的事情:

public string MyDumbProperty
{
get { return GetValue("MyDumbProperty", string.Empty); }
set { SetValue("MyDumbProperty", value);}
}

我有几个理由想要这样做。最重要的一点是,我个人不喜欢根据他们采用的参数类型命名的方法。第二个是我想为这个垃圾制作一个resharper模板。然后我可以填写属性的名称和类型并完成(假设resharper可以为该类型提供合理的默认值)。

我曾想过制作一个返回T的泛型方法GetValue,但我不确定如何设置通用约束以便这样做。从这里返回的类型都是基本类型(字符串,整数等)。有一对返回数组,但我可以总是做些不同的事情。无论如何,这不是一个高度优先的问题,但每次看到它都会让我很烦。我认为应该有更好的方法来做到这一点。

我想第一步就是重命名各种方法。由于它们在第二个参数中传递的默认值类型不同,我至少可以将它们强制为相同的名称。但我能做得更好吗?如果我可以摆脱每种方法中多个重复代码的位置,那将是很好的,只是在使用的数据类型方面不同(TryParse在所有数字类型中)。

3 个答案:

答案 0 :(得分:3)

我认为如果它的内容不太复杂,你可能能够使用泛型方法。例如,可能是这样的:

public T GetValue<T>(string name, T ifNull) where T : IConvertible
{
    string value = GetProperty(name);
    if (value == null)
        return ifNull;
    try
    {
        return (T)Convert.ChangeType(value, typeof(T));
    }
    catch
    {
        return ifNull;
    }
}

对于数组,您可能需要GetArrayValue函数来执行不同的操作。

答案 1 :(得分:2)

您可以使用default(T)来获取类型的默认值。

public T Get<T>(string propertyName)
{
    object obj;
    if (propertyBag.TryGetValue(propertyName, out obj)) {
        return (T)obj;
    }
    if(typeof(T) == typeof(string)) {
        return String.Empty;
    }
    return default(T);
}

<强>更新

作为替代方案,您可以有两个重载,一个接受显式默认值。

public T Get<T>(string propertyName)
{
    return Get<T>(propertyName, default(T));
}

public T Get<T>(string propertyName, T defaultValue)
{
    object obj;
    if (propertyBag.TryGetValue(propertyName, out obj)) {
        return (T)obj;
    }
    return defaultValue;
}

答案 2 :(得分:1)

关于.net泛型的好处是,当它们清楚地表明它们代表哪些参数时,它们可以被隐式使用。不确定那个句子上的语法,但是很可靠的是基于使用它很多...

e.g。对于GetValue:

 public T GetValue<T>(string PropertyName, T DefaultValue)
 {

 }

 .... return GetValue("Prop1", 4); //T = int
 .....return GetValue("Prop2", string.Empty) //T= string
 //for nullable times, you can always include the generic parameter
 GetValue<int[]>("Prop3",null);
 //or by 'strongly typing' the null value:
 GetValue("Prop3", (int[])null); //for set this isn't a problem, since 'value' already is strongly typed
设置

同样如此
public void SetValue<T>(string PropertyName, T Value)
{
}