Jon-Eric
Jon-Eric

Reputation: 17275

C# generic class with "conditional" constraint?

class Factory<Product> where Product : new()
{
    public Factory()
        : this(() => new Product())
    {
    }

    public Factory(System.Func<Product> build)
    {
        this.build = build;
    }

    public Product Build()
    {
        return build();
    }

    private System.Func<Product> build;
}

In Factory, when Product has a public default constructor, I'd like for clients to not have to specify how to construct one (via the first constructor). However I'd like to allow situations where Product does not have a public default constructor (via the second constructor).

Factory's generic constraint is required to allow the implementation of the first constructor, but it prohibits use with any class without a public default constructor.

Is there a way to allow for both?

Upvotes: 3

Views: 1704

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500675

Not directly, but you could use a non-generic Factory factory (sic) with a generic method, put the type constraint on the type parameter for the method, and use that to supply the delegate to the unconstrained Factory<T> class.

static class Factory
{
    public static Factory<T> FromConstructor<T>() where T : new()
    {
        return new Factory<T>(() => new T());
    }
}

class Factory<TProduct>
{
    public Factory(Func<TProduct> build)
    {
        this.build = build;
    }

    public TProduct Build()
    {
        return build();
    }

    private Func<TProduct> build;
}

Upvotes: 8

Related Questions