10

在委托的C# 文档中,它说“委托是一种引用类型,可用于封装命名或匿名方法。委托类似于 C++ 中的函数指针;但是,委托是类型安全且安全的”

我的问题是,他们所说的“安全”代表是什么意思?

4

5 回答 5

8

委托强制执行对方法的类型安全调用。这通常通过编译器执行的静态类型检查来工作。但不是唯一的方法,你可以使用Delegate.DynamicInvoke()来绕过编译器类型检查。一个例子:

using System;

class Program {
    delegate void foo(long arg);
    static void Main(string[] args) {
        var obj = new Example();
        var dlg = Delegate.CreateDelegate(typeof(foo), obj, "Target");
        dlg.DynamicInvoke(42);
    }
}

class Example {
    private long field;
    public void Target(long arg) {
        field = arg;
    }
}

现在开始修改这段代码,你可以做一些事情来欺骗类型系统:

  • 更改 foo 委托声明
  • 传递不同的委托类型作为第一个参数
  • 将不同类的对象作为第二个参数传递
  • 更改目标方法名称
  • DynamicInvoke在调用中传递不同类型的参数
  • DynamicInvoke在调用中传递一组不同的参数

所有这些尝试都将毫无怨言地编译。它们都不会执行,你会得到运行时异常。这就是使委托安全的原因,您不能使用它们来调用会使堆栈不平衡的方法或诱导目标方法访问未初始化或不属于激活框架的堆栈位置。恶意软件劫持代码的传统方式。C 或 C++ 中不存在此类运行时检查,它们的编译器仅执行静态检查,并且可以通过简单的强制转换绕过。

于 2012-07-07T15:25:28.797 回答
5

我的问题是,他们所说的“安全”是什么意思?

使用委托调用的函数被赋予调用者的安全上下文,这可以防止委托执行低权限调用者不可用的任务。可以使用指向在任何地方实现的函数的指针来初始化委托。唯一的限制是签名。在调用包含指向未知来源的函数指针的委托时,调用者需要小心,因为可能会出现意外的实现。使用代码访问安全性来保护代表。

信用: http ://etutorials.org/Programming/programming+microsoft+visual+c+sharp+2005/Part+III+More+C+Language/Chapter+8+Delegates+and+Events/

于 2012-07-07T14:24:21.787 回答
2

在这种情况下,我认为安全意味着委托不能持有无效值。这可能与类型安全部分有一点重叠。

于 2012-07-07T14:18:07.560 回答
2

这意味着您不能像在 C/C++ 中那样“乱搞”,使函数指针指向无效的内存区域,或者更糟的是,指向恶意代码。

于 2012-07-07T14:19:06.253 回答
2

它将它们与 C++ 中的函数指针进行比较,正如该人所说,它可以用来“炸掉你的腿”。

于 2012-07-07T14:19:14.163 回答