Опция будет использовать ограничение "новый":
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
Случай строки - это особый случай, поскольку он является ссылочным типом, он может иметь значение null и не имеет общедоступного конструктора по умолчанию, который вы получаете здесь вместо String.Empty. Обнуляемый тип также дает ноль.