5

I have started to learn c#. I am trying to declare a class and some variables and trying to do a simple concatenation of strings. But i am getting some error - the code is below

namespace ConsoleApplication1
{
    class Class1
    {
        string s1 = "hi";
        string s2 = "hi";
        string s3 = s1 + s2;
    }
}

The error i am getting is - a field initializer cannot reference the non-static field, method, property 'ConsoleApplication1.Class1.s1

Can someone explain what is happening here.

Thanks.

0

3 Answers 3

15

Can someone explain what is happening here.

Well, the compiler error message says it all, really, once you've got past the terminology. This line is invalid:

string s3 = s1 + s2;

You're declaring instance variables, and instance variable initializers (s1 + s2 here) aren't allowed to refer to other fields within the instance that's being created - or indeed the instance itself. Bear in mind that the above declaration is equivalent to:

string s3 = this.s1 + this.s2;

From section 10.5.5.2 of the C# 4 specification:

A variable initializer for an instance field cannot reference the instance being created. Thus it is a compile-time error to reference this in a variable initializer, because it is a compile-time error for a variable initializer to reference any instance member through a simple-name.

(Admittedly that's one of the more odder bits of wording in the spec...)

You have to put the logic into the constructor body instead:

class Class1
{
    string s1 = "hi";
    string s2 = "hi";
    string s3;

    public Class1()
    {
        s3 = s1 + s2;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

8

Variables are not [logically] initialized in a particular order. It is best to design your programs such that they will work regardless of the order that the variables are initialized.

For non-trivial assignments of local variables you use a constructor for that type:

class Class1
{
    string s1 = "hi";
    string s2 = "hi";
    string s3;

    public Class1()
    {
         s3 = s1 + s2;
    }
}

7 Comments

This is incorrect. From section 10.5.5 of the C# 4 spec (the version I happen to have to hand): "Likewise, when an instance of a class is created, all instance fields in that instance are first initialized to their default values, and then the instance field initializers are executed in textual order." (Emphasis mine.)
@JonSkeet I edited the wording. Regardless of whether the implementation happens to have an order, from a conceptual standpoint, it doesn't, and it's best to develop as if it is unordered.
This is fairly easily confirmed using the debugger. I've definitely noticed that behaviour on instance field initialization in my own code.
@Servy: I didn't quote an implementation detail. I quoted the specification. See also section 10.5.5.2. I agree it's best not to use this, as it makes the code brittle - but it's well-specified (unless you're using partial classes, where "textual order" isn't well-defined). Also note that static initializers have no such restriction.
@JonSkeet: I am reminded of the immortal words often attributed to Abraham Lincoln: how many legs does a sheep have if you call the tail a leg? Four; calling a tail a leg does not make it one.
|
6

Try initializing s3 in a method, preferably a constructor

class Class1
{
    string s1 = "hi";
    string s2 = "hi";
    string s3;


    public Class1()
    {
        s3 = s1 + s2;
    }
}

1 Comment

It's not the fact that it's doing "arithmetic" (string concatenation) here which is the problem - it's the fact that it's implicitly using this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.