Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#, instantiating a generic type - with variable type argument?

Tags:

c#

generics

Code example:

void Foo(params object[] objects)
{
    var entries = new List<IEntry>();
    foreach(var o in objects)
    {
        var entry = new Entry<o.GetType()>(); // this doesn't work
        entries.Add(entry);
    }

    ...
}

Foo("hello", 5); // should fill entries with Entry<string> and Entry<int>

Why is that not possible? I guess I need to work with reflection instead? How to do that properly AND performant?

like image 409
D.R. Avatar asked Oct 13 '25 01:10

D.R.


1 Answers

You just can't use C# generics the way you're trying to do in your snippet.

In order to use [C#] generics, the actual object type must be known at compile time.

You're trying to dynamically pass the object type as a type parameter. This is simply not possible.

Edit

Yes, it is possible to dynamically create generic objects using reflection. After all, generics is implemented both as a compile-time C# construct and as a .NET framework feature (as opposed to, say, Java, where it is only a compile-time feature based on Type Erasure). So, in .NET, through reflection, it is possible to implement the latter "bypassing" the former (which, again, would be impossible in Java).

But the OP clearly does not need that.

After all, entries is a List<IEntry>. IOW, the entries container does not "know" the concrete type of its elements (since it is bound to an interface). So, if each element to be add already implements IEntry, then this would be enough:

void Foo(params IEntry[] objects)
{
    var entries = new List<IEntry>();
    foreach(var o in objects)
    {
        entries.Add(o);
    }

    ...
}

OTOH, if those objects do not implement IEntry, then the OP just need a pure, ordinary, old-school list of untyped objects:

void Foo(params object[] objects)
{
    var entries = new List<object>();
    foreach(var o in objects)
    {
        entries.Add(o);
    }

    ...
}

So using reflection in order to dynamically create a generic container, even if possible, seems to be overkill for this particular use case.

like image 134
rsenna Avatar answered Oct 14 '25 17:10

rsenna