Reputation: 1740
Because I want to avoid an exception, I want to check whether a type has a parameterless constructor. How can I achieve this?
I need something like this:
bool HasDefaultConstructor<TT>(TT source)
{
return ???;
}
EDIT: I want to create an object of same type as source and if it hasn't a default constructor I want to use default(TT) instead.
What I have right now is:
static TT CreateObject<TT>(TT source)
{
try
{
if(!HasDefaultConstructor<TT>(source))
{
return default(TT);
}
return (TT)Activator.CreateInstance(source.GetType());
}
catch(Exception ex)
{
Trace.WriteLine("Exception catched!\r\n" + ex);
}
return default(TT);
}
static bool HasDefaultConstructor<TT>(TT source)
{
ConstructorInfo c = typeof(TT).GetConstructor(new Type[] { });
return c != null;
}
But the check gives me true and CreateInstance throws exception
No parameterless constructor
Solution:
bool HasDefaultConstructor(Type t)
{
return t.GetConstructor(Type.EmptyTypes) != null;
}
There were many recursive functions and iterations involved and somewhere down this way, the wrong generic function HasDefaultConstructor (with type object) has been called. Using a non generic function did the trick.
Thank you all for your constructive help.
Upvotes: 8
Views: 3403
Reputation: 25211
GetConstructor(Type.EmptyTypes)
will return the parameterless constructor, or null if one does not exist, so you can have:
return typeof(TT).GetConstructor(Type.EmptyTypes) != null;
EDIT
I'm guessing your problem is that TT
and source.GetType()
are actually two different types. source.GetType()
probably derives from TT
but has no parameterless constructor. So what you actually need to do is make the check for source.GetType()
:
bool HasDefaultConstructor(Type t)
{
return t.GetConstructor(Type.EmptyTypes) != null;
}
if(!HasDefaultConstructor(source.GetType()))
...
Upvotes: 13
Reputation: 157098
Use reflection to check if the type has a parameterless constructor. Use Type.GetConstructor
:
bool HasDefaultConstructor<TT>()
{
ConstructorInfo c = typeof(TT).GetConstructor(new Type[] { });
// A constructor without any types defined: no parameters
return c != null;
}
If you just want to create an instance of TT
, use the new
constraint:
TT CreateUsingDefaultConstructor<TT>() where TT : new()
{
return new TT();
}
As Jeppe Stig Nielsen suggested, you could use this code to also find constructors that are not public
. In my opinion, you should only use this as a last resort!
typeof(TT).GetConstructor( BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.Public
, null
, new Type[] { }
, null
)
Upvotes: 9