Identifyng Generics and Enums in a C# "where" clause  
Author Message
baruchl





PostPosted: Visual C# Language, Identifyng Generics and Enums in a C# "where" clause Top

In generics, you can add constraints on the type argument using the where clause
e.g.:
public class List<T> where T: IList…

My question is what should you put in the where clause to filter only
1. nullable types
2. enums

I already look for this in the web and didn't find an answer, so it's not trivial.
For example:

  1. All the following nulllable filters won't pass compilation: where Nullable<Struct>, where Nullable, where Nullable<T>
  2. All the following enum filters won't pass compilation: where System.Enum

Any help will be appreciated.

Thanks,
Busi



Visual C#18  
 
 
Mike Danes





PostPosted: Visual C# Language, Identifyng Generics and Enums in a C# "where" clause Top

As per C# spec a constraint can be:

1) a class type

2) the class keyword

3) the struct keyword

4) an interface type

5) a type parameter

6) new()

As you can see there is nothing that allows you to specify a particular value type (both enums and Nullable<T> are value types). The closest you can get is to use the struct constraint which allows for value types only.

 

 


 
 
baruchl





PostPosted: Visual C# Language, Identifyng Generics and Enums in a C# "where" clause Top

Hi Mike,
Thanks a lot for the quick answer.

This is quite awkward. I won't be able to use the HasValue property of a nullable type inside a generic method implementation.

Thanks anyway,
Busi


 
 
Mike Danes





PostPosted: Visual C# Language, Identifyng Generics and Enums in a C# "where" clause Top

Actually there is a trick that can be done about HasValue but it has some performance implications:

class Test<T>

{

private T data;

public Test(T data)

{

this.data = data;

}

public bool IsNull

{

get

{

// here's the trick: cast data to object and compare to null.

// casting to object force the value of data to be boxed and boxing a Nullable

// without value results in null

// however boxing is expensive because it must allocate a new object on the gc heap (if Nullable

// has a value, otherwise probably there is no performance penality).

return ((object)data == null);

}

}

}

class Program

{

static void Main(string[] args)

{

Test<int > foo = new Test<int >(2);

Console.WriteLine(foo.IsNull);

foo = new Test<int >(null);

Console.WriteLine(foo.IsNull);

}

}


 
 
baruchl





PostPosted: Visual C# Language, Identifyng Generics and Enums in a C# "where" clause Top

Mike, I should report this answer as an abuse... ;-)
I got your trick, not sure if I'll use it for this specific purpose, but I'll keep that in mind.

Thanks a lot!


 
 
Mike Danes





PostPosted: Visual C# Language, Identifyng Generics and Enums in a C# "where" clause Top


 
 
James Curran





PostPosted: Visual C# Language, Identifyng Generics and Enums in a C# "where" clause Top

I won't be able to use the HasValue property of a nullable type inside a generic method implementation

Well, if you are trying to do something like this:

void DoIt<T>(T t) where T : Nullable {,,,,}

that could be written as:

void DoIt<T>(Nullable<T> t) where T : struct { ....}



 
 
James Curran





PostPosted: Visual C# Language, Identifyng Generics and Enums in a C# "where" clause Top

Similar results can be achieved without boxing, through overloading:


bool IsNullable<T>(T t) where T:struct
{
return false;
}
bool IsNullable<T>(Nullable<T> t) where T:struct
{
return true;
}

bool IsNullable(object t)
{
return true;
}



 
 
baruchl





PostPosted: Visual C# Language, Identifyng Generics and Enums in a C# "where" clause Top

Hello James,
thanks for your posts. The last one in the tread seems to fulfill my original request.

Busi