I have a class which pulls objects from Isolated Storage. If it cannot find the object in question it returns default(T) which would be null as they are reference types. If the value returned is null I do a simple check and assign a new instance in the caller but I would prefer to do this in the storage logic.
So my question, is there a way to return a new T where the object has a default blank constructor?
An option would be use the contraint "new": http://msdn.microsoft.com/en-us/library/sd2w2ew5(v=vs.80).aspx
Like so:
public T GetNewItem()
where T: new()
{
return new T();
}
But having this constraint means that you can't use a type that doesn't have a default constructor. So you may consider to use System.Activator.CreateInstance, but remember that it may throw an exception:
T createInstance<T>()
{
try
{
return System.Activator.CreateInstance<T>();
}
catch (MissingMethodException exc)
{
return default(T);
}
}
So, it may be a good idea to know if the given type supports this early in the initialization, a way to do so follows:
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
}
}
While you are at it, why not get a delegate that creates an instance?
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]); };
}
}
An example of how to use it (compiled with 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?>()());
}
The output is:
System.Object
0
null
0
01/01/0001 12:00:00 a.m.
null
The case of string is a special case, being a referece type it can be null, and not having a public default constructor that's what you get here instead of String.Empty. The nullable type also gives null.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With