惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
A
About on SuperTechFans
Apple Machine Learning Research
Apple Machine Learning Research
The Register - Security
The Register - Security
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
人人都是产品经理
人人都是产品经理
MyScale Blog
MyScale Blog
云风的 BLOG
云风的 BLOG
博客园_首页
U
Unit 42
T
Tailwind CSS Blog
G
GRAHAM CLULEY
F
Full Disclosure
V
Vulnerabilities – Threatpost
T
Tenable Blog
月光博客
月光博客
P
Privacy & Cybersecurity Law Blog
P
Privacy International News Feed
K
Kaspersky official blog
Scott Helme
Scott Helme
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
News and Events Feed by Topic
T
The Exploit Database - CXSecurity.com
N
News and Events Feed by Topic
有赞技术团队
有赞技术团队
Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
LINUX DO - 最新话题
Recorded Future
Recorded Future
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Help Net Security
Help Net Security
The GitHub Blog
The GitHub Blog
Cisco Talos Blog
Cisco Talos Blog
SecWiki News
SecWiki News
P
Proofpoint News Feed
Security Latest
Security Latest
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
罗磊的独立博客
S
Security Affairs
M
MIT News - Artificial intelligence
L
LINUX DO - 热门话题
美团技术团队
Simon Willison's Weblog
Simon Willison's Weblog
T
Threat Research - Cisco Blogs
Stack Overflow Blog
Stack Overflow Blog
Forbes - Security
Forbes - Security
Hugging Face - Blog
Hugging Face - Blog
博客园 - Franky
V
Visual Studio Blog

博客园 - sdxd.bgl

将SQL Server中的数据显示到SharePoint中 拓展训练总结 在PowerShell中,如何获取SharePoint的默认数据库服务器 在SharePoint页面中如何显示来自其他网站的List 恢复导出XSLT List View WebPart 实战部署FAST Search Server 2010 for SharePoint Sharepoint开发中代码运行权限级别 在InfoPath中如何获取当前用户的信息(Profile) 晒晒我的家乡 关于模式的思考 利用System.Linq.Expressions实现四则运算计算器(三) 利用System.Linq.Expressions实现四则运算计算器(二) 利用System.Linq.Expressions实现四则运算计算器(一) 初识System.Linq.Expressions 请拆招:将两个已排序集合分解成两个独立部分的集合和一个共有部分的集合? 如何实现Windows服务 用javascript实现下拉列表的自动筛选功能 - sdxd.bgl - 博客园 我的生活 电脑是个神奇的东西!
小心委托
sdxd.bgl · 2007-09-19 · via 博客园 - sdxd.bgl
 

小心委托

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.Func()返回的是DelegateTest的实例a.a的值。在b.Func()中,结果也正如大家所料,是b.a的值。这时,我们再次调用a.Func()时,其值往往会以为是a.a的值,实际结果却是b.a的值。为什么如此?

我是在类实例构造中给静态代理赋值的。这时,大家回想刚才那句话“委托同时封装了对象实例和方法”,对结果就会容易理解些了。在静态代理中,不仅仅保存了类的方法,同时还保存了对象的实例。即第一次构造a的时候静态代理保存的是实例a,在构造b的时候静态代理保存的是实例b。因此就出现了调用a.Func()却得到b.a的值了!

这个问题的避免是:在使用静态代理的时候,要小心把成员方法赋给它。