问题描述
我正在尝试建立一个通用的Mediator系统,并且希望允许具有隐式运算符的消息接收消息,即使未提供其各自的类型T。
这是问题所在,我听不懂。希望有人比我聪明。
public static class Mediator
{
private static Dictionary<string,HashSet<Type>> m_typedMessages =
new Dictionary<string,HashSet<Type>>();
public static void NotifySubscribers<T>(string a_message,T a_arg,bool a_holdMessage = false)
{
TryAddTypedMessage(a_message,typeof(T));
foreach (Type type in m_typedMessages[a_message])
{
if (type == typeof(T) || HasImplicitConversion(type,typeof(T)))
{
Type thisType = typeof(Catalogue<>).MakeGenericType(new Type[] { type });
MethodInfo typedMethod = thisType.getmethod("NotifySubscribers");
typedMethod.Invoke(null,new object[] { a_message,a_arg,a_holdMessage });
}
}
}
private static bool HasImplicitConversion(Type a_baseType,Type a_targettype)
{
MethodInfo[] methods = a_baseType.getmethods(BindingFlags.Public | BindingFlags.Static);
IEnumerable<MethodInfo> implicitCasts = methods.Where(mi => mi.Name == "op_Implicit" && mi.ReturnType == a_baseType);
bool hasMatchingCast = implicitCasts.Any(mi =>
{
ParameterInfo pi = mi.GetParameters().FirstOrDefault();
return pi != null && pi.ParameterType == a_targettype;
});
return hasMatchingCast;
}
HasImplicitConversion工作正常。对于我的测试,我有一个类,我制作了一个名为ColorData的类,它看起来像这样:
public class ColorData
{
public float r,g,b,a;
public static implicit operator ColorData(float a_float)
{
ColorData cd = new ColorData
{
r = a_float,g = 2f * a_float,b = a_float / 3f,a = 1f
};
return cd;
}
}
一切顺利,并且通过所有检查,直到到达typedMethod.Invoke,尽管从float到ColorData进行了隐式转换,它仍然会抛出此错误:
ArgumentException:无法将类型为“ System.Single”的对象转换为类型为“ SubTestUI + ColorData”的对象。 System.RuntimeType.CheckValue(System.Object值,System.Reflection.Binder绑定器,System.Globalization.CultureInfo文化,System.Reflection.BindingFlags invokeAttr)(位于:0) System.Reflection.MonoMethod.ConvertValues(System.Reflection.Binder绑定程序,System.Object [] args,System.Reflection.ParameterInfo [] pinfo,System.Globalization.CultureInfo文化,System.Reflection.BindingFlags invokeAttr)(位于 :0) System.Reflection.MonoMethod.Invoke(System.Object obj,System.Reflection.BindingFlags invokeAttr,System.Reflection.Binder绑定程序,System.Object []参数,System.Globalization.CultureInfo文化)(位于:0) System.Reflection.MethodBase.Invoke(System.Object obj,System.Object []参数)(位于:0) Mouledoux.Mediation.Systems.Mediator.NotifySubscribers [T](System.String a_message,TA_arg,System.Boolean a_holdMessage)
我认为这是因为我在调用invoke时仍然只是将a_arg作为类型T传递了,但是不应该具有隐式操作只是让它通过吗?我无法将其强制转换为类型“ type”,在这种情况下,发生错误时,此类型为ColorData,但我无法将a_arg强制转换为Type。 任何帮助都表示赞赏。
解决方法
我明白了。对于其他好奇的人,这里是新代码:
df
由于我知道消息具有隐式方法,因此我在检查时通过“向外”隐式绕过整个内容。现在有了该方法,我可以使用它通过out隐式将a_arg从类型T转换为动态。