Last active
April 27, 2017 19:17
-
-
Save carusology/0480bd5227498a847180f987022ac4d8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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