在C#中将代理投射到Func
我有代码:
public delegate int SomeDelegate(int p); public static int Inc(int p) { return p + 1; }
我可以把Inc
成SomeDelegate
或者Func<int, int>
:
SomeDelegate a = Inc; Func<int, int> b = Inc;
但是我不能把Inc
成SomeDelegate
,然后用像这样的常用方法SomeDelegate
为Func<int, int>
:
Func<int, int> c = (Func<int, int>)a; // Сompilation error
我怎么能做到这一点?
SomeDelegate a = Inc; Func<int, int> b = Inc;
是简短的
SomeDelegate a = new SomeDelegate(Inc); // no cast here Func<int, int> b = new Func<int, int>(Inc);
你不能把一个SomeDelegate的实例转换成一个Func <int,int>,因为你不能把一个string转换成一个Dictionary <int,int> – 它们是不同的types。
这工作:
Func<int, int> c = x => a(x);
这是句法糖
class MyLambda { SomeDelegate a; public MyLambda(SomeDelegate a) { this.a = a; } public int Invoke(int x) { return this.a(x); } } Func<int, int> c = new Func<int, int>(new MyLambda(a).Invoke);
有一个更简单的方法来做到这一点,所有其他的答案已经错过了:
Func<int, int> c = a.Invoke;
看到这个博客文章了解更多信息。
尝试这个:
Func<int, int> c = (Func<int, int>)Delegate.CreateDelegate(typeof(Func<int, int>), b.Target, b.Method);
问题是:
SomeDelegate a = Inc;
实际上不是一个演员。 这是简短的forms:
SomeDelegate a = new SomeDelegate(Inc);
所以没有演员。 一个简单的解决scheme可以是这个(在C#3.0)
Func<int,int> f = i=>a(i);
这工作(至less在C#4.0中 – 没有在早期版本中尝试过):
SomeDelegate a = Inc; Func<int, int> c = new Func<int, int>(a);
如果你看一下IL,这个编译成和Winston的答案完全一样的代码。 以下是我刚刚写的第二行的IL:
ldloc.0 ldftn instance int32 ConsoleApplication1.Program/SomeDelegate::Invoke(int32) newobj instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object, native int)
这也正是你看到,如果你分配a.Invoke
。
顺便说一下,虽然迭戈的解决scheme更有效率,因为结果委托直接引用底层方法而不是通过其他委托,它不正确处理多播委托。 温斯顿的解决scheme确实如此,因为它只是完全推迟到另一个代表。 如果你想要一个直接的解决scheme来处理具有多个目标的委托,你需要一些更复杂的东西:
public static TResult DuplicateDelegateAs<TResult>(MulticastDelegate source) { Delegate result = null; foreach (Delegate sourceItem in source.GetInvocationList()) { var copy = Delegate.CreateDelegate( typeof(TResult), sourceItem.Target, sourceItem.Method); result = Delegate.Combine(result, copy); } return (TResult) (object) result; }
这样做对于具有单个目标的委托人来说是正确的 – 它将最终生成目标types的单个委托,该委派直接引用input委托所涉及的任何方法(以及适用的对象)。
这是同样的问题:
public delegate int SomeDelegate1(int p); public delegate int SomeDelegate2(int p); ... SomeDelegate1 a = new SomeDelegate1(Inc); SomeDelegate2 b = (SomeDelegate2)a; // CS0030
这是与以下类似的问题:
public class A { int prop { get; set; } } public class B { int prop { get; set; } } ... A obja = new A(); B objb = (B)obja; // CS0029
对象不能从一种types转换为不相关的其他types,即使这些types是完全兼容的。 缺less更好的术语:对象具有在运行时携带的types标识。 该对象创build后,该身份无法更改。 这个身份的可见performanceforms是Object.GetType()。
你可以通过使用c ++等效的c ++联合来诡计。 棘手的部分是有两个成员有[FieldOffset(0)]的结构:
[TestFixture] public class Demo { public void print(int i) { Console.WriteLine("Int: "+i); } private delegate void mydelegate(int i); [StructLayout(LayoutKind.Explicit)] struct funky { [FieldOffset(0)] public mydelegate a; [FieldOffset(0)] public System.Action<int> b; } [Test] public void delegatetest() { System.Action<int> f = print; funky myfunky; myfunky.a = null; myfunky.b = f; mydelegate a = myfunky.a; a(5); } }
- asynchronous提交或回滚事务作用域
- 使WPF应用程序看起来像Metro风格,即使在Windows 7中? (Window Chrome /主题/主题)
- CreateJobObject / SetInformationJobObject在.net中的工作示例pinvoke?
- ASP.NET MVC:隐藏的字段值不会使用HtmlHelper.Hidden呈现
- 如何从C#中的字节获取IntPtr
- 与服务器build立了连接,但在login前握手过程中发生错误
- .NET中的属性是什么?
- 为什么ReSharper想把“var”用于一切?
- 我得到无法加载资源:net :: ERR_BLOCKED_BY_CLIENT与谷歌浏览器