Syntax and usage of general restrictions

Suppose I want to create a generic method Max

that returns at most two values. I can use the common interface IComparable<T>

: [ null

check is ignored]

static T Max<T>(T x, T z) where T : IComparable<T>
{
    return x.CompareTo(z) > 0 ? x : z;
}

      

well. Now the first thing I don't get is the following extension for the above example:

static void Initialize<T>(T[] array) where T : new()
{ 
    for (int i = 0; i < array.length; i++)
        array[i] = new(T);
}

      

where would it be necessary to adopt this syntax ( new()

confuses me in this context)? Moreover, I saw the following general pattern that scares me even more.

class GenericClass<T> where T : SomeClass, Interface
                                      where U : new()
{ /* Some Code */ }

      

Here I am assuming that T

is a type constraint that is filtered from a type constraint U

. So, if so, we could write

class Magic<T>
{
    Magic<U> SomeOtherClass<U>() where U : T { /* Some Code */ }
}

      

I have this right and how many levels of such a hierarchy are possible in C #?

+3


source to share


1 answer


Well, you gave an example of where the constraint new()

is useful: if you want to populate an array with "new" objects, each of which is created by calling a parameterless constructor.

Regarding this:

class GenericClass<T> where T : SomeClass, Interface
                                  where U : new()

      

... which won't compile as it tries to constrain U

but is not declared as a type parameter.

But yours Magic<T>

will be compiled and forced to U

be appropriately compatible with T

. (The exact data is complex, see the specification.)



For example, you can call

new Magic<Stream>.SomeOtherClass<FileStream>()

      

or

new Magic<IFormattable>.SomeOtherClass<int>()

      

+4


source







All Articles