返回简单类型的泛型方法

本文关键字:泛型方法 类型 简单 返回 | 更新日期: 2023-09-27 18:36:33

好的,我有一些不太喜欢的代码。鉴于我没有写它,只是继承了它,我突然想到我可以稍微清理一下。基本上,我们有一个用于使用 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 可以为类型提供合理的默认值)。

我曾想过制作一个返回 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);
}

更新

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

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)
{
}