首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何实现只读属性

如何实现只读属性
EN

Stack Overflow用户
提问于 2010-10-13 02:29:03
回答 8查看 190.5K关注 0票数 90

我需要在我的类型上实现一个只读属性。此外,此属性的值将在构造函数中设置,并且不会更改(我正在编写一个为WPF公开自定义路由UI命令的类,但这并不重要)。

我认为有两种方法可以做到:

公共只读对象类MyClass {只读对象MyProperty =新对象();}私有只读对象类

  1. MyClass {私有只读对象my_property =新对象();公共对象MyProperty { get { return my_property;}} }

由于所有这些FxCop错误告诉我不应该有公共成员变量,第二个错误似乎是正确的方法。对,是这样?

在这种情况下,get only属性和read only成员之间有什么区别吗?

如果您有任何意见/建议等,我将不胜感激。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-10-13 02:39:10

C# 6.0添加只读自动属性

public object MyProperty { get; }

因此,当您不需要支持较旧的编译器时,您可以拥有一个真正的readonly属性,它的代码就像readonly字段一样简洁。

版本控制:

如果你只对源代码兼容性感兴趣,我认为这并没有太大的区别。

使用属性对二进制兼容性更好,因为您可以将其替换为具有setter的属性,而不会破坏编译后的代码,这取决于您的库。

约定:

你是在遵守惯例。在这种情况下,两种可能性之间的差异相对较小,遵循约定更好。它可能会回来咬你的一种情况是基于反射的代码。它可能只接受属性而不接受字段,例如属性编辑器/查看器。

序列化

从字段到属性的更改可能会破坏很多序列化程序。而且AFAIK XmlSerializer只序列化公共属性,而不序列化公共字段。

使用Autoproperty的

另一种常见的变体是使用带有私有setter的autoproperty。虽然这是一个简短的属性,但它并不强制可读性。所以我更喜欢其他的。

只读字段为自记录

不过,该领域有一个优势:

看一眼公共接口,它就清楚地表明它实际上是不可变的(除了反射)。而在属性的情况下,你只能看到你不能改变它,所以你必须参考文档或实现。

但老实说,我经常在应用程序代码中使用第一个,因为我很懒。在库中,我通常会更彻底,并遵循惯例。

票数 62
EN

Stack Overflow用户

发布于 2010-10-13 02:29:52

第二种方式是首选选项。

private readonly int MyVal = 5;

public int MyProp { get { return MyVal;}  }

这将确保MyVal只能在初始化时分配(也可以在构造函数中设置)。

正如您已经注意到的那样,这样您就不会公开内部成员,从而允许您在将来更改内部实现。

票数 70
EN

Stack Overflow用户

发布于 2015-05-07 23:15:02

随着C# 6(在VS 2015中)的引入,您现在可以拥有get-only自动属性,其中隐式支持字段为readonly (即,可以在构造函数中赋值,但不能在其他地方赋值):

public string Name { get; }

public Customer(string name)  // Constructor
{
    Name = name;
}

private void SomeFunction()
{
    Name = "Something Else";  // Compile-time error
}

现在还可以内联初始化属性(使用或不使用setter):

public string Name { get; } = "Boris";

回到这个问题,这为您提供了选项2的优点(公共成员是一个属性,而不是一个字段)和选项1的简洁性。

不幸的是,它不能保证公共接口级别的不变性(就像@CodesInChaos关于自我文档的观点一样),因为对于类的使用者来说,没有setter与拥有私有setter没有区别。

票数 54
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3917796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档