C# 多重泛型约束

24

我想知道是否可以添加多个通用约束?

我有一个Add方法,它接受一个对象(电子邮件、电话或地址),所以我在想是否可以这样做:

public void Add<T>(T Obj) 
    where T : Address
    where T : Email
    where T : Phone
{
    if (Obj is Address)
        m_Address.Add(Obj as Address);
    else if (Obj is Email)
        m_Email.Add(Obj as Email);
    else
        m_Phone.Add(Obj as Phone);
}

但我一直收到以下错误提示:

"已为类型参数 'T' 指定了约束子句。类型参数的所有约束必须在单个 where 子句中指定。"

7个回答

28

你不能这样做。为什么不只写三个方法,让编译器替你完成繁重的工作呢?

public void Add(Address address) { m_Address.Add(address); }
public void Add(Email email) { m_Email.Add(email); }
public void Add(Phone phone) { m_Phone.Add(phone); }

1
那么,如何枚举这样一个强类型泛型集合,其中包含异构类型,就像任何其他正常的IEnumerable<T>一样? - Angshuman Agarwal
@AngshumanAgarwal - 我假设这不是集合上的“Add”方法,因为这样做没有太多意义。 - Greg Beech
1
假设我有接口 IWalk,IRun 和 IBothWalkRun。现在,我想从所有类型中制作强类型异构集合,并迭代它们以打印所有实现了 IWalk,IRun 和 IBothWalkRun 的接口的类型。这样做有意义吗? - Angshuman Agarwal
@AngshumanAgarwal - 这似乎与这个问题无关。我认为你最好在这里发表评论之前提出一个新的问题。 - Greg Beech

9

CLR不允许多重继承,这正是您试图表达的内容。您希望T同时成为AddressEmailPhone(我假设这些是类名)。因此这是不可能的。更糟糕的是,整个方法都没有意义。您需要为所有三个类引入一个基础接口或使用三个Add方法的重载。


11
@Anton,我认为原帖提到的是OR约束(不是AND)。 - bruno conde

5

你可以为这三种类型创建一个接口或基类,如何看待这个建议呢?

但是看着你的代码,似乎没有充分利用泛型。使用泛型的好处在于你不需要将其转换为任何特定类型(在这种情况下,你正在进行强制类型转换)。


3

就像其他人所说,在您的特定情况下,应该使用继承或方法重载而不是泛型。然而,如果您确实需要创建具有多个约束条件的通用方法,则可以按照以下方式执行。

public void Foo<T>() where T : Bar, IBaz, new()
{
    // Your code here
}

3
在这种情况下,泛型并不能带来任何实际的好处。我建议为每个参数类型创建不同的“Add”方法。

1
在这种情况下,我不会费心,因为您无论如何都在比较类型。请使用以下代码:
public void Add(object Obj)
{
    if (Obj is Address)
        m_Address.Add(Obj as Address);
    else if (Obj is Email)
        m_Email.Add(Obj as Email);
    else if (Obj is Phone)
        m_Phone.Add(Obj as Phone);
    else
        return;
}

我认为不支持多个从句。你也可以使用单独的方法重载。


-4

其中 T:C1、C2、C3。用逗号分隔约束条件。尝试使用基类或接口。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接