X和Y的通用约束

ser*_*0ne 0 .net c# generics type-constraints

可以使用泛型约束来对抽象类的类型派生实施约束,但只能使用实现接口的约束吗?

例:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在C#中强制执行这样的依赖?

现有解决方案

我目前的解决方案如下:

static void INeedToDoBoth(Dependency dependency, IOptionalDependency optional)
{
    dependency.IMustDoThis();
    if (something)
    {
        optional.IMightDoThis();
    }
}
Run Code Online (Sandbox Code Playgroud)

但这意味着我将相同的参数传递两次,看起来很脏!

INeedToDoBoth(dependency, dependency);
Run Code Online (Sandbox Code Playgroud)

我考虑的另一个解决方法是:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 7

听起来你只是缺少在约束中将类和接口指定为以逗号分隔的列表的能力:

static void INeedToDoBoth<T>(T dependency)
    where T : Dependency, IOptionalDependency
Run Code Online (Sandbox Code Playgroud)

请注意,类约束必须先到此处.

有关更多详细信息,请参阅MSDN页面了解类型参数约束或C#5规范部分10.1.5.