简体   繁体   中英

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.

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.

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 ). And of course the use of const is limited by the type of the value.

The difference between const and static readonly is that the const value will be replaced on the call site. 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.

The property requires a method call (calling a getter is a method call). 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.

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. 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.

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 . 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.

readonly is nice to use on things that can only be changed in your constructor. Examples of this is typical services as interfaces when you are following the TDD pattern.

In your example const is best, it's a constant after all.

readonly

const

Cheers

The main advantage for me is with readonly you are allowed to declare it anywhere in your code. But, you will get a chance to set it only once . With the setter, you declare and set in one stroke.

I think the first line making something constant or rather readonly using readonly keyword.

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.

Yes, there's a difference between the two.

A readonly field can only be set in the constructor.

A {get; private set;} {get; private set;} can be set at anytime from within the class.

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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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