4

I want Fullname to consist of FirstName and Lastname but I get the following exception:

A field initializer cannot reference the non static field, method or property 'Employee.FirstName' / 'Employee.LastName'

class Employee
{
    public string FirstName { get; }
    public string LastName { get; }
    private string FullName = string.Format("{0}, {1}", FirstName, LastName);
}
Yuval Itzchakov
  • 136,303
  • 28
  • 230
  • 296
jeroen
  • 51
  • 4
  • I'm OCDing over the use of the `String` class instead of `string` ;P – Yuval Itzchakov Oct 13 '15 at 13:04
  • 1
    @YuvalItzchakov I should indeed use **string** instead of **String** but it has become a habit from using java :) – jeroen Oct 13 '15 at 13:10
  • 1
    string is a keyword short cut to System.String, so technically String is more correct than string. but from a common use point of view its the other way round. so can be argued both ways with equal validity http://stackoverflow.com/questions/7074/whats-the-difference-between-string-and-string – MikeT Oct 13 '15 at 13:39

3 Answers3

9

The assignment order of class fields isn't guaranteed by the run-time. That's why the compiler is warning you with a compile time error.

If FullName was a public property, you'd be able to do:

class Employee
{
    public string FirstName { get; }
    public string LastName { get; }
    public string FullName => $"{FirstName} {LastName}";
}

For anyone not using C#-6:

class Employee
{
    public string FirstName { get; private set; }
    public string LastName { get; private set; }
    public string FullName 
    {
        get { return string.Format("{0} {1}", FirstName, LastName); } 
    }
}

Or if you don't want it to be public, you'll need to instantiate the fields via the class constructor

class Employee
{
    public Employee(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
        fullName = $"{FirstName} {LastName}";
    }

    public string FirstName { get; }
    public string LastName { get; }
    private string fullName;
}
Yuval Itzchakov
  • 136,303
  • 28
  • 230
  • 296
  • 1
    OP is using a auto getter only property (no `private set`). I'm assuming he's using C#-6. He's free to downgrade this to C#-5 if needed. – Yuval Itzchakov Oct 13 '15 at 12:52
  • @InvisiblePanda Doesn't need a `=>` operator, he can set it inside the class constructor, unlike previous C# versions where you had to explicitly have a private setter. – Yuval Itzchakov Oct 13 '15 at 12:54
  • @Yuval Itzchakov wasn't criticising your answer just making the point for anyone else reading the answer and not using c#6 who can't see why its not working for them – MikeT Oct 13 '15 at 12:57
  • @InvisiblePanda: `public String FirstName { get; }` looks like a property to me. – David Oct 13 '15 at 12:58
  • @MikeT I've added an implementation for previous versions. – Yuval Itzchakov Oct 13 '15 at 12:58
  • @InvisiblePanda: Then you are indeed misunderstanding the answerer. Note his earlier comment: `"OP is using a auto getter only property [...] I'm assuming he's using C#-6"`. In that comment he was referring to, well, the auto getter only properties. – David Oct 13 '15 at 13:00
  • In which case i think you've now provided the perfect answer +1 – MikeT Oct 13 '15 at 13:02
  • 1
    @InvisiblePanda: Try using `public string FirstName { get; }` in a class definition in pre-6 C#. – David Oct 13 '15 at 13:05
  • @David Ahhh, thanks, I finally understood! Seems like I got used to that syntax already (or thought of interfaces maybe)... now it's all cleared up. I will erase my other comments, since they clutter it up and don't add anything :) – InvisiblePanda Oct 13 '15 at 13:08
  • @YuvalItzchakov (just for my understanding) - is there any difference between `private string fullName { get { return FirstName + ", " + LastName; } }` and solutions you mentioned? or I did not get what OP requires. – Zeeshan Oct 15 '15 at 07:34
  • @Zeeshan Using a property on a private field is weird. You could do that, but I wouldn't go down that path. – Yuval Itzchakov Oct 15 '15 at 07:51
  • @YuvalItzchakov I don't know why, I feel like `private string FullName { get { return string.Format("{0} {1}", FirstName, LastName); } }` this is equivalent to what I mentioned. This is using `string.Format` to add strings, and that one is using `+` *(string concatination)* to add strings. – Zeeshan Oct 15 '15 at 08:03
  • @YuvalItzchakov and I would like to know, in what sense it looks weird? If I were you, Why would I not go down that path? – Zeeshan Oct 15 '15 at 08:05
2

you are trying to set the value before you have initialised the variable

if you change from a set to a get then you will have more success

class Employee{
    public String FirstName { get; }
        public String LastName { get; }
        public String FullName {
            get{
                return String.Format("{0}, {1}", FirstName, LastName);
            }
        }
    }
}
MikeT
  • 4,398
  • 2
  • 23
  • 34
  • 1
    this is the same answer as @Yuval Itzchakov only using the older c#, and his answer is fuller and more complete – MikeT Oct 13 '15 at 12:55
1

I think you need to put that in the class constructor. The error is because you are trying to use values that don't exist, or rather might not at the time you are using them.

Code Gorilla
  • 667
  • 8
  • 20