簡體   English   中英

C#:從泛型調用外部程序集中的重載方法

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

我有一個項目引用包含幾個重載實例方法的第三方c#程序集。 我想通過代碼中的泛型調用其中一個方法,調用其參數類型與泛型類型匹配的實例方法:

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'

我最接近的是通過使用動態變量,但這會導致運行時異常,因為參數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);
    }
}

異常:結果消息:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:'VendorLib.GetVal(ref bool)'的最佳重載方法匹配具有一些無效參數

供應商庫包含幾個GetVal重載,其中GetVal(ref bool)為1, GetVal(ref ulong)另一個。

為什么沒有綁定正確的方法?

謝謝!

如果您不想檢查typeof(T)並手動調用相應的方法,則反射可以起作用。 像這樣......

  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];
    }
  }

並稱之為......

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

valdynamic ,而不是boolulong 這是錯誤的類型。 通過使用dynamic您只是在編譯時檢查中欺騙自己,而只是在運行時獲取錯誤。

看看這段代碼的工作方式,泛型和動態的唯一目的是找到一種方法將bool或ulong傳遞給GetVal(...)。 從您的代碼看起來,可能需要公開的唯一方法是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();
}

然后,任何調用Caller()的代碼都將針對IMyClass編寫,因此無需關心您使用的實現。

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

有很多模式可以解決這類問題。 為了更好地理解你真的需要花費大量時間閱讀C#中的OOP,並花時間編碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM