簡體   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