C#是否可以创建可选的泛型类型约束

时间:2011-07-15 14:10:16

标签: c# generics type-constraints

我想我知道答案,但是我需要指定泛型方法可以基于两个可选约束来获取类型。那就是T可以是一种或另一种。

public WebPage Click<T>(Func<WebPage> predicate) where T : LinkBase || FieldBase, new()
{
    WebDriver.FindElement(new T().LinkPath).Click();
    WebDriver.Wait();
    return predicate.Invoke();
}

我知道目前没有这样的语法,但有没有办法解决这个问题而不重复约束两种类型的方法?如果没有,这是否可能用于该语言的未来版本?

3 个答案:

答案 0 :(得分:6)

如果LinkBaseFieldBase没有公共基础或实现公共接口,那么这样做是没有意义的。如果他们这样做,那么你可以简单地使用那个作为约束。

我说它没有意义,因为使用类型约束的原因是为了确保使用的实际泛型类型参数支持已知的公共接口(否则,你可能只是使整个事物变为非-generic并使用object)。但是如果你有一个假设的“或”约束,那么编译器如何能够确保你在泛型中编写的代码对于最终被指定的类型参数实际上是有意义的呢?

答案 1 :(得分:3)

你是对的,没有办法将多种类型传递给通用方法。

你能掌控这两种类型吗?你能让它们各自实现相同的接口或抽象类吗?

答案 2 :(得分:2)

此类问题的一个选项是将适配器模式应用于您的类。在这种情况下,它们共享相同的属性,但不是相同的接口。 (如果您不控制源,这对于他们在正常情况下实际共享接口没有意义,这是非常有用的。)

interface ILinkablePath
{
    string LinkPath { get; }
}

class LinkBaseAdapter : ILinkablePath 
{
    private LinkBase linkBase;

    public LinkBaseAdapter(LinkBase linkBase) 
    {
        this.linkBase = linkBase;
    }

    public string LinkPath { get { return this.linkBase.LinkPath; } }
}

您可以为要支持的每个类编写适配器。如果它们不共享公共接口,甚至可能不共享公共方法或属性(在名称中,如果不在执行中),那么当您希望以相同方式使用类时,可以使用此技术。

完成此操作后,您就可以在方法中使用自适应界面。

否则,对于您在此处的具体问题,您可以为您希望支持的每种类型创建不同的方法,或者(如果您只使用单个属性而不是对象的其余部分),只需传入要使用的属性的值,而不是整个对象本身。