具有类型约束的部分通用接口

时间:2017-03-20 12:36:18

标签: c# generics interface type-constraints

我需要创建两个部分接口。一个有约束而另一个没有,比如:

public partial interface IMyCuteInterface<T> where T : IEnumerable
{
    void DoSomethingOnlyPossibleIfGenericIsIEnumerable();
}

public partial interface IMyCuteInterface<T>
{
    void DoSomeStuff();
    void DoSomeStuff2();
}

这是实施:

public class CuteInterfaceImplementation<T> : IMyCuteInterface<T>
{
    private readonly T _element;
    public CuteInterfaceImplementation(T element)
    {
        _element = element;
    }

    public void DoSomethingOnlyPossibleIfGenericIsIEnumerable(){}
    public void DoSomeStuff(){}
    public void DoSomeStuff2() { }
}

这是一种更加动态的静态方法:

public class CuteInterfaceImplementationBase
{
    public static IMyCuteInterface<T> From<T>(T t)
    {
        return new CuteInterfaceImplementation<T>(t);
    }
}

这就是我想要的方式:

public static void Main(string[] args)
{
    var mci = CuteInterfaceImplementationBase.From(args);
}

所以,C#希望我将我在第一个界面中添加的泛型类型约束添加到我的CuteInterfaceImplementationBase.From<T>和我的CuteInterfaceImplementation<T> - 类中。

我想要达到的目标是:args可以是例如从类型List<T>或类型int或其他内容。我的目标是,如果args来自类型IEnumerable<T>,我想添加更多函数(通过带约束的接口)到CuteInterfaceImplementation - 实例。

示例:

如果args来自IEnumerable类型,则来自CuteInterfaceImplementation的此实例包含方法:

  • void DoSomethingOnlyPossibleIfGenericIsIEnumerable();
  • void DoSomeStuff();
  • void DoSomeStuff2();

如果args来自类型Fooint(或任何未实现IEnumerable的类型),我可以使用方法:

  • void DoSomeStuff();
  • void DoSomeStuff2();

表示DoSomethingOnlyPossibleIfGenericIsIEnumerable不可用。

但似乎这是不可能的,因为我需要将约束添加到我实现的类中。知道怎么做吗?

1 个答案:

答案 0 :(得分:1)

不确定这种方法是否好主意,它违反了SOLID中的“我” - interface segregation

  

不应该强迫任何客户端依赖它不使用的方法

您正在使用owl:ObjectProperty拆分两个根本不同的接口,您应该有两个不同的接口,因为它们不同。

回答您的问题: 如果您在partial的条件下致力于类似的方法,则可以拆分接口,将“公共逻辑”(两个接口都使用)移动到基类并使用T方法有条件地选择要创建的实现。

这样的事情:

From<T>

然后是实施:

public partial interface IMyCuteInterface_WITHEnumerable<T> : IMyCuteInterface<T> where T : IEnumerable
{
    void DoSomethingOnlyPossibleIfGenericIsIEnumerable();
}

public partial interface IMyCuteInterface<T>
{
    void DoSomeStuff();
    void DoSomeStuff2();
}

最后你的“静态助手”,决定要实例化的类: 不幸的是,在C#中不可能有条件地实例化不同的类,因为一个人希望public class CuteInterfaceImplementation<T> : CuteInterfaceImplementation_COMMON<T> { public CuteInterfaceImplementation(T element) : base(element) { } } public class CuteInterfaceImplementation_COMMON<T> : IMyCuteInterface<T> { private readonly T _element; public CuteInterfaceImplementation_COMMON(T element) { _element = element; } public void DoSomeStuff() { } public void DoSomeStuff2() { } } public class CuteInterfaceImplementation_WITHEnumerable<T> : CuteInterfaceImplementation_COMMON<T>, IMyCuteInterface_WITHEnumerable<T> where T : IEnumerable { private readonly T _element; public CuteInterfaceImplementation_WITHEnumerable(T element) : base(element) { _element = element; } public void DoSomethingOnlyPossibleIfGenericIsIEnumerable() { } } T而另一个则不是。您可以使用IEnumerable

来解决这个问题
dynamic