Generics used in struct vs class

2020-06-09 03:30发布

问题:

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?

回答1:

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?



回答2:

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;
    }
}


回答3:

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.



回答4:

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

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.