使用在 C# 中的泛型类中定义的泛型参数调用泛型方法

问题描述

这是我的代码

  class Program1
    {
        private static void Main(string[] args)
        {
            //MyClass myClass = new MyClass();
            //GetIdRequest getIdRequest = new GetIdRequest();
            //GetIdReponse getIdReponse= myClass.DoRequest(getIdRequest);
            //Console.WriteLine($"getIdReponse.Msg:" + getIdReponse.Msg + ",getIdReponse.Data:" + getIdReponse.Data);

            Type myClasstype = typeof(MyClass);
            Object myClasstypeInstance = System.Activator.CreateInstance(myClasstype);
            Type unboundGenericType = typeof(MyRequest<>);
            Type boundGenericType = unboundGenericType.MakeGenericType(typeof(GetIdRequest));

            Type getIdRequestType = typeof(GetIdRequest);
            Object getIdRequest = System.Activator.CreateInstance(getIdRequestType);


            MethodInfo methodInfo = myClasstype.getmethod("DoRequest",BindingFlags.Public| BindingFlags.Instance,null,new Type[] { boundGenericType },null);


            object res = methodInfo.Invoke(myClasstypeInstance,new object[] { getIdRequest });

            Console.ReadKey();
        }

    }
    public class MyClass
    {
        public T DoRequest<T>(MyRequest<T> obj) where T : MyReponse
        {
            T res = Activator.CreateInstance<T>();
            return res;
        }
    }

    public class GetIdRequest: MyRequest<GetIdReponse>
    {
    }

    public class GetIdReponse: MyReponse
    {
        public string Data { set; get; } = "data";
    }

    public interface MyRequest<T> where T: MyReponse
    {

    }

    public class MyReponse
    {
        public string Msg { set; get; } = "res";
    }

我想用运行时在泛型类中定义的泛型参数调用泛型方法 但我得到了异常

"System.ArgumentException :"" TestPlatformApi.MyRequest `Genericarguments [0] on 1 [t] "" TestPlatformApi.GetIdRequest '违反类型't'的约束"

解决方法

  1. 正如 Charlieface 评论的那样,您应该取消对 MyRequest 的限制。
  2. 根据您的代码,我无法充分了解您的设计。所以,我只是在假设下展示了一些代码。
 public class MyClass<T> where T : MsgConstraint
    {
        private IList<T> middlewares = new List<T>();

        public void Register(T m)
        {
            middlewares.Add(m);
        }

        public T DoRequest(Type type)
        {
            return middlewares.Where(st => st.GetType() == type).FirstOrDefault();
        }
    }

    public interface MsgConstraint
    {
        public string Msg { set; get; }
    }

    public class HttpMsg : MsgConstraint
    {
        public string Msg { get; set; } = "HTTPMSG";
    }

    public class RpcMsg : MsgConstraint
    {
        public string Msg { get; set; } = "RPCMSG";
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyClass<MsgConstraint> myClass = new MyClass<MsgConstraint>();
            myClass.Register(new HttpMsg());
            myClass.Register(new RpcMsg());
            MsgConstraint http = myClass.DoRequest(typeof(HttpMsg));
            Console.WriteLine(http.Msg);
            MsgConstraint rpc = myClass.DoRequest(typeof(RpcMsg));
            Console.WriteLine(rpc.Msg);
        }
    }