2012-06-06 39 views
3

好的, 我有一些我不太喜欢的代码。鉴于我没有写出它,只是继承了它,我发现我可以清理它一点。基本上,我们有一个用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)方面都不相同,那将会很棒。

+0

你看过DependancyProperty的部署方式吗?你基本上有一个DependancyProperty的模型! –

+1

这一切都取决于你的'GetValue'方法。泛型很容易做到这一点,而类型可以通过第二个参数来推断。 – vcsjones

+0

出于好奇,你是什么类型的字典?如果它存储了所有不同类型的值,它只是一个Dictionary ,它会随着人们试图避免的所有装箱/拆箱而出现? – itsme86

回答

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

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

是的,但他不能使用通用约束来限制T可以是什么。开发人员可以将它用作Get ,它在运行时会失败。 –

+0

此外,默认为空,他似乎希望字符串的默认值为string.Empty。 –

+0

它在运行时为什么会失败?只要您检索您之前存储的相同类型,任何类型都应该有效。他可以写'if(typeof(T)== typeof(string))return String.Empty;返回默认(T);'这真的是一个问题。 –

1

.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) 
{ 
} 
+0

如果我调用'GetValue ','GetValue '会做什么?我相信OP想限制T到一系列原始类型。 –

+0

他呢?我可能会误解,但我认为他只想要一个更清晰的语法来调用属性。啊,看到所有其他答案,可能是我误解了这个问题。 –

+1

好吧,经过一些反思(心理反射,而不是System.Reflection),我发现我并没有限制使用原始类型,因为我总是可以序列化为JSON并在其中填充内容。目前,这还没有发生,但我“能”做到这一点。我可能不应该。这就是说,我可以使用我的JSON序列化器来抽取任意类型(包括基元,我认为)。这可能真的简化了事情,因为它可能都在一个地方而不必复制代码。嗯,我不得不测试这个,看看它是否会伤害我的表现。 –

1

我想你也许可以逃脱的通用方法,如果它的胆量都没有太复杂。例如,可能是这样的:

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功能,做不同的东西。

+0

您将展示如何调用此函数'GetValue ' – Mou