简体   繁体   English

C# getter 与只读

[英]C# getter vs readonly

Is there any difference between the following?以下有什么区别吗?

class C
{
    // One:
    public static readonly int ValueAsAMember = 42;

    // Two:
    public static int ValueAsAProperty { get { return 42; } }
}

I'm used to writing constants the first way (unless they're private/internal, in which case I use the const keyword), but I recently saw the second form.我习惯于以第一种方式编写常量(除非它们是私有/内部的,在这种情况下我使用 const 关键字),但我最近看到了第二种形式。

Is there any advantage one way over the other in terms of readability, convention, performance, or anything else?在可读性、约定、性能或其他方面,是否有一种方式优于另一种方式?

You have three choices:你有三个选择:

  • public static readonly int Value = 42;
  • public static int Value { get { return 42; } }
  • public const int Value = 42;

Choose static readonly if the value will not change at runtime but might change in future versions of your code.如果该值在运行时不会更改但可能会在您的代码的未来版本中更改,请选择static readonly

Choose a property if the value might change at runtime.如果值可能在运行时更改,请选择一个属性。 Of course it won't change if you use the given code.当然,如果您使用给定的代码,它不会改变。

Choose const if the value is really a constant that will not even change in future versions (something like Math.PI or int.MinValue ).如果该值确实是一个在未来版本中甚至不会改变的常量(例如Math.PIint.MinValue ),则选择const And of course the use of const is limited by the type of the value.当然, const的使用受到值类型的限制。

The difference between const and static readonly is that the const value will be replaced on the call site.之间的区别conststatic readonly的是, const的值将在电话会议上现场进行更换。 If you change the value of a const in a future version then all assemblies that rely on your class need to be recompiled using the new value.如果在未来版本中更改const的值,则需要使用新值重新编译依赖于您的类的所有程序集。

The property requires a method call (calling a getter is a method call).该属性需要一个方法调用(调用 getter 是一个方法调用)。 So if the value is constant at runtime there is no need for that.因此,如果该值在运行时保持不变,则无需这样做。

Yes, there is an advantage:是的,有一个优势:

If the value gets changeable at any point in the future (eg in a future version of your code), in a way that it is, for example, time-dependent, you can support that in the read-only property without changing the public interface of your class.如果该值在未来的任何时候(例如,在您的代码的未来版本中)以某种方式(例如,与时间相关的)可变,您可以在只读属性中支持它,而无需更改公共你的类的界面。

If you have to replace a readonly field with a property, you will have to recompile any other assemblies that use your class.如果必须用属性替换readonly字段,则必须重新编译使用您的类的任何其他程序集。

There are two major differences:有两个主要区别:

The first is that fields cannot be on interfaces, whereas properties can.首先是字段不能在接口上,而属性可以。 So if you want to use this in an interface, you have to use the property.所以如果你想在接口中使用它,你必须使用该属性。

The second, more interesting, is that readonly fields CAN be modified, while the object is being constructed.第二个更有趣的是,可以在构造对象时修改readonly字段。 Take the following code:取以下代码:

public class MyTestClass
{
    public readonly int MyInt = 1;

    public MyTestClass()
    {
        MyInt = 2;
    }
}

If a caller does如果来电者

new MyTestClass().MyInt

they will get 2. The same goes for static constructors for a static readonly field.他们将得到 2。静态readonly字段的静态构造函数也是如此。

The way I see it, using the first way describes the intention of the value better - which is that it is immutable.我看它的方式,使用第一种方式更好地描述了价值的意图 - 即它是不可变的。 When a person is looking at the class' interface, he will see that the value is read-only, and won't have to wonder whether it can be changed later (since in the second case he can't see the property's implementation).当一个人在看类的接口时,他会看到该值是只读的,并且不必怀疑以后是否可以更改(因为在第二种情况下他看不到该属性的实现) .

An important thing to note about const declarations (I don't believe it's true for readonly ) is that changing the field's value constitutes an API change, even if you're just changing the value from 42 to 41 .关于const声明(我认为readonly不是这样)的一个重要事项是,更改字段的值构成 API 更改,即使您只是将值从42更改为41 The reason is that for consts , the value is determined during compile time, which means that if I compile a module that uses your constant, and you later change it, I will still be using the old value until I recompile my module with your new version.原因是对于consts ,该值是在编译时确定的,这意味着如果我编译了一个使用您的常量的模块,然后您更改了它,我仍将使用旧值,直到我用您的新模块重新编译我的模块版本。

readonly is nice to use on things that can only be changed in your constructor. readonly很适合用于只能在构造函数中更改的内容。 Examples of this is typical services as interfaces when you are following the TDD pattern.当您遵循 TDD 模式时,这方面的示例是作为接口的典型服务。

In your example const is best, it's a constant after all.在您的示例中, const是最好的,毕竟它是一个常量。

readonly只读

const常量

Cheers干杯

The main advantage for me is with readonly you are allowed to declare it anywhere in your code.对我来说,主要优点是readonly你可以在代码中的任何地方声明它。 But, you will get a chance to set it only once .但是,您将有机会仅设置一次 With the setter, you declare and set in one stroke.使用 setter,您可以一次性声明和设置。

I think the first line making something constant or rather readonly using readonly keyword.我认为第一行使用 readonly 关键字使某些内容保持不变或更确切地说是只读的。

and the second line is making use of a property to implement readonly.第二行是利用一个属性来实现只读。 Both do the same but if you compare with the IL the property would add few extra lines of code to the dll.两者都做同样的事情,但如果与 IL 进行比较,该属性会向 dll 添加几行额外的代码。

Yes, there's a difference between the two.是的,两者是有区别的。

A readonly field can only be set in the constructor. readonly字段只能在构造函数中设置。

A {get; private set;}一个{get; private set;} {get; private set;} can be set at anytime from within the class. {get; private set;}可以在课堂内随时设置。

Example:例子:

public class Car
{
    public readonly string Name;

    public string color {get; private set;}

    public Car()
    {
        Name = "Car";
        Color = "Red";
    }

    // will fail compilation
    public void ModifyName()
    {
        Name = "Subaru"
    }

    // perfectly ok
    public void ModifyColor()
    {
        Color = "Green"
    }
}

A Property is just syntactic sugar around a field, a property without a setter is simply declared a readonly field so the compiler will allow you to set it at runtime in the constructor, because to the compiler you are referencing a readonly field.属性只是围绕字段的语法糖,没有设置器的属性只是简单地声明为只读字段,因此编译器将允许您在运行时在构造函数中设置它,因为对编译器而言,您正在引用只读字段。 There is a larger discussion around what to use a field or property, which is not within the scope of the question.关于使用字段或属性的内容有更广泛的讨论,这不在问题的范围内。 And yes its this syntactic sugar that you have to do the recompiling referenced by @SOreadytohelp.是的,您必须重新编译@SOreadytohelp 引用的这种语法糖 Just to be clear a property is a field with a get and set method created for it, C# will allow you to reference it like a field rather than doing an annoying call to the getter or setter everytime.只是要明确一个属性是一个为它创建了 get 和 set 方法的字段,C# 将允许您引用字段一样引用它,而不是每次都对 getter 或 setter 进行烦人的调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM