Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What if T is void in Generics? How to omit angle brackets

Tags:

c#

void

generics

I have a class of this type:

class A<TResult>
{
     public TResult foo();
}

But sometimes I need to use this class as a non generic class, ie the type TResult is void.
I can't instantiate the class in the following way:

var a = new A<void>();

Also, I'd rather not specify the type omitting the angle brackets:

var a = new A();

I don't want re-write the whole class because it does the same thing.

like image 974
Nick Avatar asked Oct 26 '12 08:10

Nick


2 Answers

The void isn't a real type in C#, even there is a corresponding System.Void struct in FCL. I'm afraid you need a non-generic version here like this:

class A
{
   //non generic implementation
}

class A<T> : A
{
   //generic implementation 
}

you can see in FCL there are System.Action/System.Action<T>, instead of System.Action<void>, as well as Task instead of Task<void>.

EDIT From CLI specification(ECMA-335):

The following kinds of type cannot be used as arguments in instantiations (of generic types or methods):

Byref types (e.g., System.Generic.Collection.List`1<string&> is invalid)

Value types that contain fields that can point into the CIL evaluation stack (e.g.,List<System.RuntimeArgumentHandle>)

void (e.g.,List<System.Void> is invalid)

like image 122
Cheng Chen Avatar answered Sep 20 '22 04:09

Cheng Chen


As I posted in comment you can make it look good by inheriting from generic class:

class A:A<object>
{
}

This clearly hides the generic parameter but be aware that in my experience this is the wrong way to inherit classes and every time I did this I regretted it while my class got more complex.

like image 36
Rafal Avatar answered Sep 22 '22 04:09

Rafal