我刚刚意识到c#属性结构也可以与私有访问修饰符一起使用:

private string Password { get; set; }

虽然这在技术上很有趣,但我无法想象我什么时候会使用它,因为私人领域涉及的仪式甚至更少:

private string _password;

我无法想象什么时候我需要能够在内部获取但不设置或设置但不获取私有字段:

private string Password { get; }

or

private string Password { set; }

但也许有嵌套/继承类的用例,或者可能get/set可能包含逻辑,而不仅仅是返回属性的值,尽管我倾向于严格保持属性简单,让显式方法做任何逻辑,例如GetEncodedPassword()。

是否有人出于某种原因在c#中使用私有属性,或者它只是那些技术上可行但在实际代码中很少使用的结构之一?

齿顶高

不错的答案,我仔细阅读了这些私人财产的用途:

当需要惰性加载私有字段时 当私有字段需要额外的逻辑或者是计算值时 因为私有字段很难调试 为了“向自己展示一份合同” 将公开的属性作为序列化的一部分在内部转换/简化 包装要在类中使用的全局变量


当前回答

惰性初始化是它们可以很整洁的一个地方,例如。

private Lazy<MyType> mytype = new Lazy<MyType>(/* expensive factory function */);

private MyType MyType { get { return this.mytype.Value; } }

// In C#6, you replace the last line with: private MyType MyType => myType.Value;

然后你可以写:this。MyType而不是this.mytype.Value,并封装了它在单个位置被惰性实例化的事实。

一个遗憾的是c#不支持将支持字段的作用域定义为属性(即在属性定义中声明它)来完全隐藏它,并确保它只能通过属性访问。

其他回答

如果我需要缓存一个值并想要延迟加载它,我就使用它们。

private string _password;
private string Password
{
    get
    {
        if (_password == null)
        {
            _password = CallExpensiveOperation();
        }

        return _password;
    }
}

在我的代码中,它的主要用途是惰性初始化,就像其他人提到的那样。

在字段上使用私有属性的另一个原因是私有属性比私有字段更容易调试。我经常想知道一些事情,比如“这个领域正在出人意料地设置;谁是第一个设置这个字段的调用者?”如果你能在setter上放一个断点,然后点击go,那就简单多了。你可以把登录放到这里。你可以把绩效指标放进去。您可以放入在调试版本中运行的一致性检查。

基本上,这可以归结为:代码远比数据强大。任何能让我编写所需代码的技术都是好技术。字段不允许您在其中编写代码,属性允许。

我知道这个问题很老了,但下面的信息没有出现在任何当前的答案中。

我无法想象什么时候我需要内部获取而不是设置

如果你正在注入你的依赖项,你可能很想在属性上有一个Getter,而不是一个setter,因为这将表示一个只读属性。换句话说,Property只能在构造函数中设置,不能由类中的任何其他代码更改。

此外,Visual Studio Professional将提供关于属性而不是字段的信息,从而更容易看到您的字段正在被使用。

好吧,正如没有人提到的,你可以用它来验证数据或锁定变量。

Validation string _password; string Password { get { return _password; } set { // Validation logic. if (value.Length < 8) { throw new Exception("Password too short!"); } _password = value; } } Locking object _lock = new object(); object _lockedReference; object LockedReference { get { lock (_lock) { return _lockedReference; } } set { lock (_lock) { _lockedReference = value; } } } Note: When locking a reference you do not lock access to members of the referenced object.

惰性引用:当惰性加载时,你可能最终需要异步加载,现在有AsyncLazy。如果你使用的是比Visual Studio SDK 2015更老的版本,或者没有使用它,你也可以使用AsyncEx的AsyncLazy。

我在序列化中使用它们,比如DataContractSerializer或protobuf-net,它们支持这种用法(XmlSerializer不支持)。如果你需要简化一个对象作为序列化的一部分,它是有用的:

public SomeComplexType SomeProp { get;set;}
[DataMember(Order=1)]
private int SomePropProxy {
    get { return SomeProp.ToInt32(); }
    set { SomeProp = SomeComplexType.FromInt32(value); }
}