ArgumentException:无法转换类型的对象但是我有一个隐式运算符C#

问题描述

我正在尝试建立一个通用的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转换为动态。