我有一个项目引用包含多个重载实例方法的第三方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)
为另一个。
为什么没有绑定正确的方法?
谢谢!
答案 0 :(得分:2)
如果您不想检查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>();
答案 1 :(得分:1)
val
是dynamic
,而不是bool
或ulong
。这是错误的类型。通过使用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,并花时间编写代码。