C#是否可以创建可选的通用类型约束条件

问题描述 投票:7回答:4

我想我知道这个问题的答案,但是我需要指定一个通用方法可以根据两个可选的约束条件来取一个类型。那就是T可以是一种类型,也可以是另一种类型。

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

我知道目前没有这样的语法,但是有没有一种方法可以解决这个问题,而不需要重复的方法对两种类型进行约束?如果没有,这是否在未来语言版本的可能性范围内?

c# generics type-constraints
4个回答
3
投票

你说的对,没有办法在一个通用方法中传入多种类型。

你能控制这两种类型吗?你能让它们各自实现同一个接口或抽象类吗?


6
投票

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

我说这是没有意义的,因为使用类型约束的原因是为了确保实际使用的通用类型参数支持一个已知的公共接口(否则,你可以把整个东西做成非通用的,然后使用 object). 但是如果你有一个假设的 "或 "约束,编译器如何能够确保你在泛型里面写的代码对于最终指定的类型参数会有实际意义呢?


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; } }
}

你可以为你想要支持的每个类写一个适配器。如果它们不共享一个共同的接口,甚至可能不共享共同的方法或属性(在名称上,如果不是在执行上),那么当你希望以同样的方式使用这些类时,你可以使用这种技术。

当你做到了这一点,你就能够干净利落地在你的方法中使用自适应接口。

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


0
投票

话题很老,但对于未来的读者来说。

这个功能与以下内容密切相关 Discriminated Unions 目前在C#中还没有实现。我在这里发现了它的问题。

https:/github.comdotnetcsharplangissues113

这个问题仍未解决,功能已计划在以下时间段使用 C# 10

所以我们还是要再等一下,但是发布之后你可以这样做。

public WebPage Click<T>(Func<WebPage> predicate) where T : LinkBase | FieldBase, new()
{
    WebDriver.FindElement(new T().LinkPath).Click();
    WebDriver.Wait();
    return predicate.Invoke();
}
© www.soinside.com 2019 - 2024. All rights reserved.