简体   繁体   中英

Need help understanding C# generics

I am self-studying a C# reference and it gives the following information:

1.21.4. Declaring Generic Parameters Generic parameters can be introduced in the declaration of classes, structs, interfaces, delegates (see the upcoming "Delegates" section), and methods. Other constructs, such as properties, cannot introduce a generic parameter, but can use a generic parameter. For example, the property Value uses T:

public struct Nullable<T>
{
  public T Value {get;}
}

First, I get an error trying to compile this saying that it must contain a body because it is neither abstract nor extern or that automatic parameters must have both get and set accessors.

Second, assuming it is wrong and I correct it by adding "set;", I cannot seem to format a call to it successfully.

That is just showing the API of Nullable<T> rather than the implementation. It's not meant to be compiled - System.Nullable<T> is part of the framework, you don't have to implement it yourself.

You appear to be reading "C# 3.0 in a Nutshell". Well, the example is just that - an example. It is only intended to illustrate how the Value property of the Generic Nullable class exposes the generic parameter declared by the containing type.

It isn't meant to be part of a compilable example.

I'm not sure if you just picked a bad example for your struct name (since Nullable is a framework struct), but if not, the error is due to the fact that you have no set accessor in your property. Automatic properties (added in C# 3.0) need both a get and set property. So, if you change the code to:

public struct Nullable<T>
{
  public T Value {get; set; }
}

it should work. In this case, the error had nothing to do with generics. To create an instance, you could use:

Nullable<int> i = new Nullable<int>();

This will make it compile. However, as both Jon and Cerebrus has pointed out, it's probably just an example to show the workings of generics.

For an automatic property you always need both a getter and setter. Without a getter you could set the value, but nothing could ever retrieve it. Without a setter the value would always be the default because nothing could ever set it:

//tradition 
private T _value; 
public T Value 
{ 
    get 
    {
        return _value;
    }
}
//locally, _value can always be set

//Auto-matically implemented property
public T Value { get; }
//there is never a way to set it

//with this it can be privately set, but is get only to everyone else
public T Value{ get; private set; }

Your question here seems to be about auto-properties, rather than generics.

Auto-properties must have a set accessor, although it doesn't have to have the same visibility as the get:

public T Value { get; private set; }

You can call the set in the constructor:

public Nullable ( T value ) {
    Value = value;
}

Although in this case you're dealing with a struct, and they always have a default (parameterless) constructor - you have to be a bit more careful with structs and auto-properties.

In .net there's already a nullable generic:

Nullable<int> i = GetCounterThatMightBeNull();

int j = 0;
if( i.HasValue )
    j = i.Value;
...

This was added in .Net 2 (at the same time as generics), and while early betas looked like the code above they streamlined it the final version:

//int? is shorthand for Nullable<int>
int? i = GetCounterThatMightBeNull(); 

// ?? is shorthand for the null check
int j = i ?? 0;

//or
if( i == null ) {
    //this works even though Nullable<int> is a struct
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM