当我尝试为实现接口的值类型方法创建开放实例委托时,Delegate.CreateDelegate 失败。因为实例方法是值类型,所以第一个参数必须是 ref,所以让我们为此定义一个通用委托类型:
delegate T2 VF<T0, T1, T2>(ref T0 arg0, T1 arg1);
现在这是一个程序,它成功地为 int.ToString(string) 创建了一个开放实例委托,但未能为 int.Equals(int) 创建一个开放实例委托:
class Program
{
static void Main(string[] args)
{
var tos = typeof(int).GetMethod("ToString", new[] { typeof(string) });
var tosopen = Delegate.CreateDelegate(
typeof(VF<int, string, string>), null, tos);
// success!
var eq = typeof(int).GetMethod("Equals", new[] { typeof(int) });
var eqopen = Delegate.CreateDelegate(
typeof(VF<int, int, bool>), null, eq);
// previous line fails with "Error binding to target method"
}
}
这似乎是由于 int.Equals(int) 实现的事实IEquatable<int>
。请注意,以下操作确实有效:
var x = typeof(IEquatable<int>).GetMethod("Equals", new Type[] { typeof(int) });
var xopen = Delegate.CreateDelegate(
typeof(Func<IEquatable<int>, int, bool>), null, x);
xopen(1,1); // returns true
但这并不是我想要的,因为这似乎将作为第一个参数传递的任何整数装箱。我也不想比较任何IEquatable<int>
,我想专门调用方法来比较两个整数。
对这里有什么问题有任何想法吗?
这里提到了一个似乎直接相关的 Microsoft Connect 错误,但该链接不再适用于我,而且我无法通过搜索找到该错误。
编辑:请注意,在尝试为覆盖方法创建开放实例委托时会出现同样的问题,因此它不仅仅是接口方法。