Sleiman Jneidi
Sleiman Jneidi

Reputation: 23329

Generics used in struct vs class

Assume that we have the following struct definition that uses generics:

public struct Foo<T>
{
    public T First; 
    public T Second;

    public Foo(T first)
    {
        this.First = first;
    }

}

The compiler says

'Foo.Second' must be fully assigned before control is returned to the caller

However, if Foo is a class, then it compiles successfully.

public class Foo<T>
{
    public T First; 
    public T Second;

    public Foo(T first)
    {
        this.First = first;
    }

}

Why? Why the compiler treats them differently? Moreover if no constructor is defined in the first Foo then it compiles. Why this behaviour?

Upvotes: 16

Views: 37821

Answers (4)

Jeff
Jeff

Reputation: 12785

The other answers explain the behaviour correctly, but neglect to mention the second part of your question, so here it is for completion.

For classes, when you don't explicitly define a constructor, the compiler will produce a default constructor which assigns default values (e.g. null for objects, 0 for numbers etc.) to every field.

For structs, the struct always has an implicit parameterless constructor that assigns default values.

Upvotes: 0

SergeyS
SergeyS

Reputation: 3553

Because it is a rule in C# that all fields must be assigned for structs (inline or in constructor). This is because of a struct nature. It has nothing about generic it or not generic.

Upvotes: 2

driis
driis

Reputation: 164301

That is because a compiler rule enforces that all fields in a struct must be assigned before control leaves any constructor.

You can get your code working by doing this:

public Foo(T first)
{
    this.First = first;
    this.Second = default(T);
}

Also see Why Must I Initialize All Fields in my C# struct with a Non-Default Constructor?

Upvotes: 22

user27414
user27414

Reputation:

That's a requirement of structs in general -- it has nothing to do with generics. Your constructor must assign a value to all fields.

Note the same error happens here:

struct Foo
{
    public int A;
    public int B;

    public Foo()
    {
        A = 1;
    }
}

Upvotes: 15

Related Questions