检查对象的类型是Dictionary还是Union of Dictionaries



我有一个函数

public static async void MyFunction(object Obj)
{
if (Obj.GetType() == typeof(Dictionary<string, string>))
{
// My Code
}
}

我想检查参数Obj的类型是Dictionary<string, string>还是Dictionary<string, string>.Union(Dictionary<string, string>)

如果传递给函数的对象类型为DictionaryUnion of Dictionaries,那么我应该在上面的if语句中设置什么||条件,以便它执行if块?

我该怎么做?

使用扩展方法:

public static bool IsAssignableToGenericType(this Type givenType, Type genericType) {
if (givenType.IsGenericType && givenType.IsGenericEqual(genericType))
return true;
if (givenType.GetInterface(genericType.Name) != null)
return true;
foreach (var it in givenType.GetInterfaces())
if (it.IsAssignableToGenericType(genericType))
return true;
var baseType = givenType.BaseType;
if (baseType == null)
return false;
return baseType.IsAssignableToGenericType(genericType);
}

您可以测试:

if (Obj.GetType().IsAssignableToGenericType(typeof(IEnumerable<KeyValuePair<string,string>>))) {

这并不保证Obj是对Union的调用的产物。如果你需要这样做,你需要深入研究类型。

使用一些扩展方法使反射更容易:

public static class ObjectExt {
public static object GetPrivateValue<T>(this T obj, string memberName) =>
obj.GetType().GetPropertyOrField(memberName, BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public).GetValue(obj);
}
public static class TypeExt {
public static MemberInfo GetPropertyOrField(this Type t, string memberName, BindingFlags bf = BindingFlags.Public | BindingFlags.Instance) =>
t.GetMember(memberName, bf).Where(mi => mi.MemberType == MemberTypes.Field || mi.MemberType == MemberTypes.Property).Single();
}
public static class MemberInfoExt {
public static object GetValue(this MemberInfo member, object srcObject) {
switch (member) {
case FieldInfo mfi:
return mfi.GetValue(srcObject);
case PropertyInfo mpi:
return mpi.GetValue(srcObject);
case MethodInfo mi:
return mi.Invoke(srcObject, null);
default:
throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or MethodInfo", nameof(member));
}
}
}

您可以确定该对象来自DictionaryUnion。请注意,这取决于.Net Core的内部结构,将来可能不起作用:

var isDictUnion = (Obj.GetType() == unionType) && (Obj.GetPrivateValue("_first").GetType() == dictType) && (Obj.GetPrivateValue("_second").GetType() == dictType);