Skip to content

Instantly share code, notes, and snippets.

@carusology
Last active April 27, 2017 19:17
Show Gist options
  • Save carusology/0480bd5227498a847180f987022ac4d8 to your computer and use it in GitHub Desktop.
Save carusology/0480bd5227498a847180f987022ac4d8 to your computer and use it in GitHub Desktop.
public ConstructorInfo FindConstructor(string[] names, Type[] types)
{
var constructors = _type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (ConstructorInfo ctor in constructors.OrderBy(c => c.IsPublic ? 0 : (c.IsPrivate ? 2 : 1)).ThenBy(c => c.GetParameters().Length))
{
// (1) Don't use an array. Use a name => parameter info mapping that is case insensitive.
// Added benefit here, if we get two parameters with the same name but in a case-insensitive
// match, an exception will be thrown. Today no exception is thrown, even though it is unsupported.
IDictionary<String, ParameterInfo> ctorParameters =
ctor.GetParameters()
.ToDictionary(parameter => parameter.Name, StringComparer.OrdinalIgnoreCase);
if (ctorParameters.Count == 0)
return ctor;
if (ctorParameters.Count != types.Length)
continue;
int i = 0;
for (; i < ctorParameters.Count; i++)
{
// (2) When getting the constructor parameter to check, check by name instead of index:
ParameterInfo parameter;
if (!ctorParameters.TryGetValue(names[i], out parameter)) {
break;
}
// (3) That's it. everything else here is the same, with ctorParameters[index] swaping to parameter.
if (types[i] == typeof(byte[]) && parameter.ParameterType.FullName == SqlMapper.LinqBinary)
continue;
var unboxedType = Nullable.GetUnderlyingType(parameter.ParameterType) ?? parameter.ParameterType;
if ((unboxedType != types[i] && !SqlMapper.HasTypeHandler(unboxedType))
&& !(unboxedType.IsEnum() && Enum.GetUnderlyingType(unboxedType) == types[i])
&& !(unboxedType == typeof(char) && types[i] == typeof(string))
&& !(unboxedType.IsEnum() && types[i] == typeof(string)))
{
break;
}
}
if (i == ctorParameters.Count)
return ctor;
}
return null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment