lifeformed
lifeformed

Reputation: 525

How do I design a generic method with a new() constraint if it's only taking in non-concrete objects?

I'm having trouble designing this system that creates instances from a prototype object. Here's what I have:

Dictionary<Type, IFoo> Prototypes;
object CreateInstance(Type type)
{
    IFoo value;
    if (!Prototypes.TryGetValue(type, out value))
    {
        value = Activator.CreateInstance(type) as IFoo;
        Prototypes.Add(type, value);
    }
    return Create(value as object);
}

T Create<T>(T instance) where T : new()
{
    return new T(); // this just returns a new blank object
}

I know that the problem is that I can't guarantee these objects to have a parameterless constructor. But what can I do then? There's no way to specify in IFoo to have a parameterless constructor, is there? The only thing I can think of is to have a simple Create() function specified in IFoo, but I was hoping there'd be a solution that doesn't involve injecting a ton of new boilerplate code into my codebase.

And I can't call Activator.CreateInstance() every time, because of performance issues (I'll be running this function a lot).

Thanks for any suggestions.

Upvotes: 0

Views: 35

Answers (1)

Blorgbeard
Blorgbeard

Reputation: 103457

The problem is that generics are a compile-time feature. You are trying to create objects where the type is determined at run-time.

Therefore, you can't use generics to do this.

When you call Create(value as object);, the type parameter T is object (because it's inferred at compile-time from the compile-time type of the argument), so you get a new object() returned.

You could call Create<Foo> and get another Foo instance, but there's just no way to take Type type and call the appropriate Create<Type> without heavy use of reflection.

Upvotes: 2

Related Questions