繁体   English   中英

返回简单类型的泛型方法

[英]Generic methods returning simple types

好的,我有一些我不太喜欢的代码。 鉴于我没有写它而只是继承它,我发现我可以将它清理一下。 基本上,我们有一个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在所有数字类型中)。

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

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函数来执行不同的操作。

您可以使用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);
}

UPDATE

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

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;
}

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

例如,对于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)
{
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM