2011-07-16 54 views
2

我有一個從孤立存儲中提取對象的類。如果它找不到有問題的對象,它將返回默認值(T),因爲它們是引用類型,所以它將爲空。如果返回的值爲空,我會做一個簡單的檢查並在調用者中分配一個新實例,但我更願意在存儲邏輯中執行此操作。在泛型中返回一個新實例而不是空實例

所以我的問題,有沒有辦法返回一個新的T的對象有一個默認的空白構造函數?

+0

可能的重複[通過Activator.CreateInstance創建可爲空的對象返回null](http://stackoverflow.com/questions/8691601/creating-a-nullable-object-via-activator-createinstance-returns- null) – nawfal

回答

13

一種選擇是使用該限制的「新」: http://msdn.microsoft.com/en-us/library/sd2w2ew5(v=vs.80).aspx

像這樣:

public T GetNewItem() 
    where T: new() 
{ 
    return new T(); 
} 

但有這個限制意味着,沒有你不能使用類型默認構造函數。所以,你可以考慮使用System.Activator.CreateInstance,但請記住,它可能會拋出異常:

T createInstance<T>() 
{ 
    try 
    { 
     return System.Activator.CreateInstance<T>(); 
    } 
    catch (MissingMethodException exc) 
    { 
     return default(T); 
    } 
} 

因此,它可能是知道好主意,如果給定類型支持的初始化這個月初,方法如下:

T createInstance<T>() 
{ 
    System.Reflection.ConstructorInfo constructor = (typeof(T)).GetConstructor(System.Type.EmptyTypes); 
    if (ReferenceEquals(constructor, null)) 
    { 
     //there is no default constructor 
     return default(T); 
    } 
    else 
    { 
     //there is a default constructor 
     //you can invoke it like so: 
     return (T)constructor.Invoke(new object[0]); 
     //return constructor.Invoke(new object[0]) as T; //If T is class 
    } 
} 

當你在這裏,爲什麼不能創建一個實例的委託?

Func<T> getConstructor<T>() 
{ 
    System.Reflection.ConstructorInfo constructor = (typeof(T)).GetConstructor(System.Type.EmptyTypes); 
    if (ReferenceEquals(constructor, null)) 
    { 
     return() => { return default(T); }; 
    } 
    else 
    { 
     return() => { return (T)constructor.Invoke(new object[0]); }; 
    } 
} 

的如何使用它的示例(編譯LinqPad):

void Main() 
{ 
    Console.WriteLine(getConstructor<object>()()); 
    Console.WriteLine(getConstructor<int>()()); 
    Console.WriteLine(getConstructor<string>()()); 
    Console.WriteLine(getConstructor<decimal>()()); 
    Console.WriteLine(getConstructor<DateTime>()()); 
    Console.WriteLine(getConstructor<int?>()()); 
} 

的輸出是:

System.Object 
0 
null 
0 
01/01/0001 12:00:00 a.m. 
null 

字符串的情況下,是一種特殊的情況下,作爲一個referece鍵入它可以爲null,並且不具有公共默認構造函數,而不是String.Empty。可空類型也給出null。

+0

非常全面的歡呼聲! – deanvmc

2

new()約束添加到您的泛型方法:

public T Create<T>() where T: class, new() 
{ 
    return new T(); 
} 
3

您可以將約束添加到您的類型參數,但將排除被不支持空參數的構造函數的類用作類型參數。

public class Foo<T> where T : new() 
{ 
    // Now you can say T blah = new T(); 
} 

您也可以撥打Activator.CreateInstance<T>(),但如果類型沒有正確的構造函數將拋出。

我認爲如果找不到對象,並且讓調用代碼處理它認爲合適的條件,你可能會更好,因爲記錄下你的方法返回null。知道如何繼續下去將是最好的選擇。

1

此作品:

使用系統;

public class Test 
{ 
    static T CreateT<T>(bool _new) where T: new() 
    { 
     if (_new) return new T(); else return default(T); 
    } 
    public static void Main() 
    { 
     var o = CreateT<object>(true); 
    } 
} 
相關問題