简体   繁体   English

C#:从泛型调用外部程序集中的重载方法

[英]C#: Call overloaded method in external assembly from generic

I have a project that references a 3rd party c# assembly containing several overloaded instance methods. 我有一个项目引用包含几个重载实例方法的第三方c#程序集。 I want to invoke one of these methods via a generic in my code, calling the instance method whose parameter type matches the type of the generic: 我想通过代码中的泛型调用其中一个方法,调用其参数类型与泛型类型匹配的实例方法:

void GetVal<T>(ref T val)
{
    VendorLib v = new VendorLib();
    v.GetVal(ref val); 
}

// error CS1503: Argument 1: cannot convert from 'ref T' to 'ref bool'

The closest I have come is through the use of a dynamic variable, but this results in a runtime exception as the parameter d resolves to bool even though the type of the generic is ulong, thereby binding the incorrect method: 我最接近的是通过使用动态变量,但这会导致运行时异常,因为参数d解析为bool,即使泛型的类型是ulong,从而绑定了不正确的方法:

class MyClass
{
    void Caller()
    {
        ulong val = 0;
        this.GetValue<ulong>(ref val);
    }

    void GetValue<T>(ref T val)
    {
        dynamic d = val; 
        GetValDynamic(ref d);
    }

    void GetValDynamic(ref dynamic val)
    {
        VendorLib v = new VendorLib();
        v.GetVal(ref val);
    }
}

Exception: Result Message: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : The best overloaded method match for 'VendorLib.GetVal(ref bool)' has some invalid arguments 异常:结果消息:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:'VendorLib.GetVal(ref bool)'的最佳重载方法匹配具有一些无效参数

The vendor library contains several GetVal overloads, of which GetVal(ref bool) is one and GetVal(ref ulong) another. 供应商库包含几个GetVal重载,其中GetVal(ref bool)为1, GetVal(ref ulong)另一个。

Why is the correct method not being bound? 为什么没有绑定正确的方法?

Thanks! 谢谢!

If you don't want to check typeof(T) and call the respective method manually then reflection can work. 如果您不想检查typeof(T)并手动调用相应的方法,则反射可以起作用。 Something like this... 像这样......

  public class MyVendorLibWrapper
  {
    private readonly VendorLib vendorLib;

    public MyVendorLibWrapper()
    {
      this.vendorLib = new VendorLib();
    }

    public T GetValue<T>()
    {
      MethodInfo method = typeof(VendorLib)
        .GetMethod("GetVal", new Type[] { typeof(T).MakeByRefType() });

      object[] arguments = new object[] { default(T) };
      method.Invoke(this.vendorLib, arguments);
      return (T)arguments[0];
    }
  }

And called something like this... 并称之为......

MyVendorLibWrapper wrapper = new MyVendorLibWrapper();
int x = wrapper.GetValue<int>();

val is a dynamic , not a bool or a ulong . valdynamic ,而不是boolulong It is the wrong type. 这是错误的类型。 By using dynamic you are just cheating yourself out of the compile-time checking and just getting an error at runtime instead. 通过使用dynamic您只是在编译时检查中欺骗自己,而只是在运行时获取错误。

Looking at the way this code works the only purpose of generics and dynamic is to find a way to pass either a bool or a ulong to GetVal(...). 看看这段代码的工作方式,泛型和动态的唯一目的是找到一种方法将bool或ulong传递给GetVal(...)。 From your code it looks like the only method that might need to be public is Caller(), in which case you can hide all this behind a common interface. 从您的代码看起来,可能需要公开的唯一方法是Caller(),在这种情况下,您可以将所有这些隐藏在公共接口之后。

class MyClassULong : IMyClass
{
    void Caller()
    {
        ulong val = 0;
        this.GetValue(ref val);
    }

    void GetValue(ulong val)
    {
        VendorLib v = new VendorLib();
        v.GetVal(ref val);
    }

}

class MyClassBool : IMyClass
{
    void Caller()
    {
        bool val = false;
        this.GetValue(ref val);
    }

    void GetValue(bool val)
    {
        VendorLib v = new VendorLib();
        v.GetVal(ref val);
    }

}

public interface IMyClass
{
    void Caller();
}

Then any code invoking Caller() would be written against IMyClass, and therefore wouldn't care which implementation you used. 然后,任何调用Caller()的代码都将针对IMyClass编写,因此无需关心您使用的实现。

public void CallIt(IMyClass myClass)
{
    myClass.Caller();
}

There are lots of patterns to get round this type of problem. 有很多模式可以解决这类问题。 For a better understanding you really need to spend a good deal of time reading about OOP in C#, and spend time coding. 为了更好地理解你真的需要花费大量时间阅读C#中的OOP,并花时间编码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM