【问题标题】:C# anonymous backing fields with non-auto properties具有非自动属性的 C# 匿名支持字段
【发布时间】:2011-08-05 03:56:14
【问题描述】:

我想创建一个私有成员变量,即使对于拥有它的类也是私有的,并且只能由它的 getter 和 setter 访问。 我知道你可以使用自动属性来做到这一点,比如

private int MyInt{ get; set;}

但我希望能够修改 getter 和 setter,因此(例如)我可以记录该字段已设置的次数(即使是所属类)。像这样的

private int MyInt
{
    get{ return hiddenValue; }
    set{ hiddenValue = value; Console.Out.WriteLine("MyInt has been set");}
}

其中“hiddenValue”是只能在 getter 和 setter 中访问的成员。 为什么?因为我是一个偏执的防御性程序员,我什至不相信自己:p。

这在 C# 中可行吗?如果是的话,语法是什么?

谢谢。

【问题讨论】:

  • 有比偏执狂更充分的理由来争取这个:)。缓存属性并不罕见,即在第一次访问时,通过数据库等检索值并存储在支持字段中,而对于后续访问,getter 使用支持字段。在这一点上,开发人员,尤其是那些刚接触项目的开发人员,可能不清楚是使用属性还是支持字段。

标签: c# .net c#-4.0 c#-3.0 defensive-programming


【解决方案1】:

你真的应该相信自己。

不,你不能让一个变量如此私有,即使封装类也看不到它。

如果你真的想要这个,你可以将值封装在一个嵌套类中,它能够覆盖它自己的私有内容。

class Foo 
{
    class Bar // nested
    {
        private int _value;
        public int Value 
        {
            get { return _value; }
            set { _value = value; /* logic */ }
        }
    }
}

Foo 可以实例化 Bar,获取 bar.Value,但无法获取 _value。

【讨论】:

  • +1 但话又说回来,他无论如何都可以使用反射来更改值,但仍然不够偏执。
  • 老鼠,这对于在维护期间使代码防白痴很方便。好吧,没有什么是白痴证明,但它会有所帮助。不幸的是,把它放在一个封装类中会增加太多的代码复杂性和出错的机会:p
  • @Bryan,你知道什么会毁了你的一天吗?你准备好了吗? Foos 的单独实例可以看到彼此的私人信息。您不仅不能从实例中隐藏成员,而且不能从同​​一类的另一个实例中隐藏它。
  • @BrokenGlass 是的,但他们必须努力绕过访问者。这更多是为了确保即使更改是内部引起的,也会触发 onChange 事件。您如何对匿名支持成员使用反射?过去几年我一直在 java 领域,所以我只是再次复习我的 C#,但我似乎记得需要成员名称通过反射来修改它。
  • @Bryan,考虑一下,一旦它被编译,它就不是“匿名的”。自动实现的属性为您节省了定义支持字段的麻烦,但这并不意味着没有。您刚刚将创建它的负担交给了编译器。
【解决方案2】:

.Net 中的任何语言都不可能。而且很好。防御性编码固然不错,但一旦变得偏执,就会让其他需要维护它的开发人员发疯。

【讨论】:

  • 需要防御性编程正是因为其他开发人员需要维护它!
  • 我仍然喜欢使用很好的解决方案(AOP,代码合同),但是当您开始检查发送者和参数以获取空引用并且无意在以后的代码中使用它们时,我我想知道为什么这种偏执狂会适得其反。
  • @Mark H... 完全正确!我总是认为在我之后工作的人是个彻头彻尾的白痴。即使我是那个白痴。如果我可以保证访问器总是被调用,那么我肯定知道我的事件总是会被触发并且数据总是被验证。
【解决方案3】:

面向方面的编程 (AOP) 可能会有所帮助,简而言之,它允许您在方法调用之前和/或之后注入您选择的代码。

查看http://code.google.com/p/easyprop/,这是一个专门为观察属性变化而设计的 AOP 库,并且有使用自动属性的示例。

注意:我还没有使用图书馆,但它看起来就在你的小巷里。

【讨论】:

  • +1 用于提及 AOP。不过,我认为PostSharp 是更好的框架。
  • 我现在正在查看 PostSharp。对这个问题没有太大帮助,但总的来说它看起来确实很有帮助:p
【解决方案4】:

不,这在 C# 中是不可能的。

你最好的选择可能是减少偏执。 :P

【讨论】:

    【解决方案5】:

    您正在尝试做的事情,在 .NET 中无法实现。

    即使是隐藏的支持字段在 IL 代码中也是可见的。这意味着虽然您在设计时(在 VS 中)看不到它,但它会在编译后出现。

    【讨论】:

      猜你喜欢
      • 2015-06-07
      • 1970-01-01
      • 1970-01-01
      • 2015-03-28
      • 1970-01-01
      • 2017-02-11
      • 1970-01-01
      • 2019-02-03
      • 1970-01-01
      相关资源
      最近更新 更多