






















小心委托
在C#语言规范中,对委托(delegate)的描述有这么一句话:“委托同时封装了对象实例和方法”,我用一段小程序来说明这句话的含义,以解答各位在使用委托时出现的奇怪现象。
首先定义一个delegate,一个不带参数,只返回字符串的简单委托类型:
public delegate string ReturnStringFunc();
下面的类使用了这个委托,请大家留意委托的使用方法:
public class DelegateTest
{
public DelegateTest()
{
func = GetA;
}
private static ReturnStringFunc func;
public ReturnStringFunc Func
{
get
{
return func;
}
}
private string a;
public string A
{
get { return a; }
set { a = value; }
}
public string GetA()
{
return a;
}
static void Main()
{
DelegateTest a = new DelegateTest();
a.A = "A";
Console.WriteLine(a.Func());
DelegateTest b = new DelegateTest();
b.A = "B";
Console.WriteLine(b.Func());
Console.WriteLine(a.Func());
Console.ReadLine();
}
}
这个类中,定义了一个内部静态变量func,然后通过成员属性Func将其公开。另外写了个成员方法GetA(),并在构造函数中把成员方法GetA()赋给静态变量func。成员方法GetA()直接返回类成员变量a。
在Main()函数中测试调用Func()方法情况。输出结果如下:
A
B
B
即,第一个a.Func()返回的是DelegateTest的实例a.a的值。在b.Func()中,结果也正如大家所料,是b.a的值。这时,我们再次调用a.Func()时,其值往往会以为是a.a的值,实际结果却是b.a的值。为什么如此?
我是在类实例构造中给静态代理赋值的。这时,大家回想刚才那句话“委托同时封装了对象实例和方法”,对结果就会容易理解些了。在静态代理中,不仅仅保存了类的方法,同时还保存了对象的实例。即第一次构造a的时候静态代理保存的是实例a,在构造b的时候静态代理保存的是实例b。因此就出现了调用a.Func()却得到b.a的值了!
这个问题的避免是:在使用静态代理的时候,要小心把成员方法赋给它。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。