Generic constraint of X AND Y

353 views Asked by At

Can generic constraints be used to enforce a constraint on type derivatives of an abstract class, but only those that implement an interface?

Example:

abstract class Dependency
{
    public abstract void IMustDoThis();
}

interface IOptionalDependency
{
    void IMightDoThis();
}

sealed class AlmightyDependency : Dependency, IOptionalDependency
{
    // I have sealed this for a reason!

    public override void IMustDoThis()
    {
        // I am almighty because I do this!
    }

    public void IMightDoThis()
    {
        // I am almighty because I can do this too!
    }
}

class ThisIsntTheAnswer : AlmightyDependency
{
    // AlmightyDependency is sealed...this is not the answer I'm looking for!
}

static class DoSomeAlmightyWork
{
    static void INeedToDoBoth<T>(T dependency) where T : Dependency ...AND... IOptionalDependency
    {
        dependency.IMustDoThis();
        if (something)
        {
            dependency.IMightDoThis();
        }
    }
}

Is there any way to enforce such a dependency in C#?

Current Solutions:

My current solution is as follows:

static void INeedToDoBoth(Dependency dependency, IOptionalDependency optional)
{
    dependency.IMustDoThis();
    if (something)
    {
        optional.IMightDoThis();
    }
}

But this means I pass the same parameter twice, which looks dirty!

INeedToDoBoth(dependency, dependency);

Another workaround I have considered is:

static void INeedToDoBoth(IOptionalDependency optional)
{
    Dependency dependency = optional as Dependency;
    if(dependency != null)
    {
        dependency.IMustDoThis();
        // But if I MUST do this, and I was null...then what?
    }

    if (something)
    {
        optional.IMightDoThis();
    }
}
1

There are 1 answers

2
Jon Skeet On BEST ANSWER

Sounds like you're just missing the ability to specify both a class and interfaces as a comma-separated list in the constraints:

static void INeedToDoBoth<T>(T dependency)
    where T : Dependency, IOptionalDependency

Note that the class constraint must come first here.

See the MSDN page for type parameter constraints or the C# 5 specification section 10.1.5 for more details.