Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'private static readonly' fields and static/nonstatic constructors

Tags:

c#

modifier

I have three objects :

private static readonly Apple a, c;
private readonly Orange b;

This code is called from my constructor :

public SomeClass()
{
    a = new Apple();
    b = new Orange(a.getDna());
    c = new Apple(b.getDna());
}

It gives me the error Readonly field cannot be used as an assignment target. If I remove either the static or readonly modifiers, it compiles perfectly. (Is there a wrong warning here?)

On checking other answers here on SO, I found that I should use a static constructor like :

static SomeClass()
{
    a = new Apple();
    c = new Apple(b.getDna());
}

public SomeClass()
{
    b = new Orange(a.getDna());
}

But this would cause the static constructor to be called first and cause an error since b would not be initialized.

How do I circumvent this?

P.S. I'm relatively new to C#

like image 280
Hele Avatar asked Apr 21 '15 04:04

Hele


People also ask

What is difference between private and static constructor?

1. Static constructor is called before the first instance of class is created, wheras private constructor is called after the first instance of class is created. 2. Static constructor will be executed only once, whereas private constructor is executed everytime, whenever it is called.

What is difference between readonly and static?

Constant and ReadOnly keyword is used to make a field constant which value cannot be modified. The static keyword is used to make members static that can be shared by all the class objects.

What is a static constructor?

A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed only once. It is called automatically before the first instance is created or any static members are referenced.

Can static class have private constructor?

Use private constructor when class have only static members. Using private constructor, prevents the creation of the instances of that class.


2 Answers

Let's start by defining what is static and what's the difference between static and instance members.

A static member is a member that doesn't need an instance to exist: it "belongs to the class", and not to an object (a instance of the class).

Now the readonly modifier, says that a member can only be assigned a value in the constructor (or in its declaration, but that's not relevant here).

There are two types of constructors: static constructors and instance constructors... the difference is the same difference as above, and the readonly modifier is of course, applied to each type of constructor: static readonly would mean "you can only change its value in the static constructor", and instance readonly would mean "you can change its value in the instance constructor".

The static constructor is called the first time the type is accessed, so it's always called first.

Now, in the examples you are just randomly changing members to static or not just to try if it compiles.

Think about it for a second... in the static context you have no instance at all, so it's just not possible to access instance members on the static constructors... furthermore, by the time the static constructor is called, there's no way you could have any initialized instance, even externally defined, since it'll always be called before you have the chance to initialize one.

So this line within the static constructor makes no sense:

c = new Apple(b.getDna());

You are trying to access b, which is an instance member, but you are not saying which instance should you get the value from.

You should really rethink your design, and think why members would be static or not, not just "move things around and try to make it compile and run".

like image 168
Jcl Avatar answered Sep 27 '22 21:09

Jcl


The error is correct because if you create another instance of SomeClass the static field a will be assigned twice, against the readonly constraint.

like image 24
Paolo Costa Avatar answered Sep 27 '22 22:09

Paolo Costa