在C#中私密'设置' - 在我周围缠绕我的大脑时遇到困难

Maj*_*ons 19 c# private

我已经看到很多使用类似的东西编写的示例代码(请原谅这是多么可怕的罐头):

public class Test
{
   public object Thingy { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这些例子从未真正解释为什么'set'被设置为私有.所以,我只是想知道是否有一个好的,常见的例子可以向我说明为什么会使用这样的东西.

我有点看到它 - 除了设置该字段外,还可以运行属性来处理一些额外的逻辑.我只是对如何调用它感到困惑,为什么会使用这种方法而不是通用的setter方法.

spi*_*non 24

如果你有一个你不希望任何人设置的属性,那就是你的类.这对于数据库ID来说非常方便.内部类可以设置它,但你不希望任何其他人改变它.所以你可以给他们读取权限而不是写入.

编辑:还有一点是,使用您展示的内容对自动属性很有帮助.不幸的是,对于自动属性,你不能只指定get,以免公开暴露一个setter它只是私有.

编辑:只是想我会举一个例子.自动属性非常适合干净,简洁的代码.但是就像你展示的那样,你必须得到并设定一个限制.所以在此之前像你所展示的房产一样:

public class Test
{
   private object thingy;
   public object Thingy
   {
      get { return thingy; }
   }
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以摆脱那种不必要的私人声明,但它需要两者.所以私下来解决这个问题.

我知道这对解释来说太过分了,但不同的事情一直在我的脑海中浮现.


Mar*_*ell 9

举个简单的例子; 它是一种制作"不可变的"对象的廉价方法(用于线程,状态等).而且任何地方的客户根本不应该需要指定它,或者不能被信任到(正确地)分配给它.

另一个例子可能是一个列表:

public List<Foo> Items {get;private set;}
Run Code Online (Sandbox Code Playgroud)

因为我们可以打电话obj.Items.Add()等,但我们很少会分配obj.Items = ....但是,这个例子在构造函数中需要显式初始化,并且XmlSerializer讨厌它 - 对于我主要使用的列表诚实:

private readonly List<Foo> items = new List<Foo>();
public List<Foo> Items {get { return items;}}
Run Code Online (Sandbox Code Playgroud)

这解决了这两个问题.

另一个例子,对比:

private readonly int foo;
public int Foo {get{return foo;}}
Run Code Online (Sandbox Code Playgroud)

VS

private readonly int foo;
public int Foo {get{return foo;} private set {foo=value;}}
Run Code Online (Sandbox Code Playgroud)

这种模式在序列化中可能很有用,例如DataContractSerializer(添加一些属性),因为许多序列化程序仍然会寻找私有访问器.这避免了我们必须装饰我们的内部状态(foo),但给了隐私的贴面set.

最终,任何东西都可以绕过并通过反射分配,因此私有set只是为了避免意外损坏数据.