我有一個從孤立存儲中提取對象的類。如果它找不到有問題的對象,它將返回默認值(T),因爲它們是引用類型,所以它將爲空。如果返回的值爲空,我會做一個簡單的檢查並在調用者中分配一個新實例,但我更願意在存儲邏輯中執行此操作。在泛型中返回一個新實例而不是空實例
所以我的問題,有沒有辦法返回一個新的T的對象有一個默認的空白構造函數?
我有一個從孤立存儲中提取對象的類。如果它找不到有問題的對象,它將返回默認值(T),因爲它們是引用類型,所以它將爲空。如果返回的值爲空,我會做一個簡單的檢查並在調用者中分配一個新實例,但我更願意在存儲邏輯中執行此操作。在泛型中返回一個新實例而不是空實例
所以我的問題,有沒有辦法返回一個新的T的對象有一個默認的空白構造函數?
一種選擇是使用該限制的「新」: 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。
非常全面的歡呼聲! – deanvmc
的new()
約束添加到您的泛型方法:
public T Create<T>() where T: class, new()
{
return new T();
}
您可以將約束添加到您的類型參數,但將排除被不支持空參數的構造函數的類用作類型參數。
public class Foo<T> where T : new()
{
// Now you can say T blah = new T();
}
您也可以撥打Activator.CreateInstance<T>()
,但如果類型沒有正確的構造函數將拋出。
我認爲如果找不到對象,並且讓調用代碼處理它認爲合適的條件,你可能會更好,因爲記錄下你的方法返回null
。知道如何繼續下去將是最好的選擇。
此作品:
使用系統;
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);
}
}
從Generic method to instantiate a variable of any type (including nullable struct)?
public static T GetEmpty<T>() where T : new() //this constraint is important
{
return (T)Activator.CreateInstance(Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T));
}
這適用於爲空的結構爲好。對於int?
,它返回0並且不爲空。更快的方法here.
可能的重複[通過Activator.CreateInstance創建可爲空的對象返回null](http://stackoverflow.com/questions/8691601/creating-a-nullable-object-via-activator-createinstance-returns- null) – nawfal