【问题标题】:C# readonly vs GetC# 只读 vs 获取
【发布时间】:2016-09-26 13:49:32
【问题描述】:

readonly 修饰符和 get-only 属性之间有什么区别吗?

例子:

public class GetOnly
{
    public string MyProp { get; }
}

public class ReadOnly
{
    public readonly string MyProp;
}

奖励:有没有办法制作一个同时适用于两者的界面? (与泛型一起使用)

public interface ISomething
{
    public string MyProp { get; }
}

public class GetOnly : ISomething
{
    public string MyProp { get; }
}

public class ReadOnly : ISomething // Cannot implement
{
    public readonly string MyProp;
}

非常感谢!

【问题讨论】:

  • 您可以通过显式实现在 ReadOnly 类上实现接口

标签: c# properties


【解决方案1】:

在以下部分:

public class GetOnly
{
    public string MyProp {get; }
}

MyProp 是一个property。但是,在这部分:

public class ReadOnly
{
    public readonly string MyProp;
}

MyPropfield。这是两个不同的东西。

有没有办法制作一个同时兼容两者的界面?

没有。只有属性可以放入接口。字段不能。

【讨论】:

    【解决方案2】:

    乍一看,属性和字段在功能上是等效的,对于存储数据和传递数据的正常用例,使用它们并没有太大区别。

    但是您似乎已经发现了一个重要问题:只有属性才能成为接口的一部分。

    有没有办法制作一个同时兼容两者的界面?

    没有。

    此外,许多依赖反射(EF、序列化)的 API 专门寻找属性。

    【讨论】:

    • 太棒了!我正在查看哪个内存会更轻,并试图让事情变得更干燥。
    • @robjam 如果您考虑使用只读变量而不是仅获取属性,则应该考虑根本不使用任何方法,而只使用静态 void main(得到讽刺?)。 get only 属性是一个私有的只读字段和一个返回值的公共 void。没有其他的。 - tryroslyn.azurewebsites.net/…
    • 您忘记了两个重点:1) 属性不仅可以是接口的一部分,还可以是基类的一部分,并且可以在类到类的层次链中被覆盖。 2) 只有属性可以用作 WPF 绑定中的源。
    • 覆盖确实适用于只读内容。我可以在基类中创建一个只读的{ get; } 属性并将其设为虚拟。子类 DO 可以覆盖它,可能在他自己的构造函数中分配一个不同的常量值,甚至更改整个逻辑,创建一个私有字段并执行:get { return _privateField; } 使该字段非只读,因此在类中可以更改。 “WPF 只是这些 API 中的另一个”是什么意思?它是在 Windows 中构建桌面应用程序的王子框架,所以这不是你可以轻易忽略的区别......o.O'
    【解决方案3】:

    一个是字段(readonly);另一个是财产。接口不能定义字段,只能定义属性、方法、索引器和事件。

    两者都只能通过构造函数或字段初始化来赋值,之后不能更改。

    【讨论】:

    • @downvoter,请对我的回答有什么问题发表评论;如果您的建议有效,我会很乐意改进它。
    • @HenkHolterman 我根据您的回复修改了我的答案(关于private set)。谢谢!
    【解决方案4】:

    您从根本上误解了这两个定义的含义。只有暴露 getter 才能说明值是否是只读的nothing

    在这个简单的例子中:

    public class GetOnly
    {
        public string MyProp { get; }
    }
    

    我们可以说MyProp永远改变它的值,我们不能总是说只有getter 的属性不会改变它的值。例如,我们无法看到 GetOnly 的实现,只知道公共定义 - 例如,如果您使用的是闭源第三方库。

    一个更清楚的例子是这样的:

    public interface ISomething
    {
        string MyProp { get; }
    }
    

    这个界面没有说MyProp是只读的。它说 不能更改该属性。它没有说明财产的行为。更糟糕的是,它只是说当显式转换为 ISomething 时不能更改属性。

    完全可以像这样实现接口(即使接口只公开了 getter):

    public class GetOnly : ISomething
    {
        public string MyProp { get; set; }
    }
    

    readonly 是一个修饰符,它明确强制值永远不会改变,除非在声明或构造函数中(除非像reflection 这样的变通方法)。

    但是,readonly 不能用于属性,因为属性只是获取/设置方法的语法糖。此外,接口仅定义方法,因此您无法定义字段(以及扩展的只读字段)。

    所以回答你的问题:是的,它们是天壤之别,只是表面上相似。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-08
      • 2020-09-05
      • 1970-01-01
      • 2018-05-03
      • 2021-08-02
      相关资源
      最近更新 更多