C# 泛型 - 我可以让 T 来自两个选择之一吗?
假设我有以下类层次结构:
Class A {...}
Class B : A {...}
Class C : A {...}
我目前拥有的是
Class D<T> where T : A {...}
,但我想要某种形式的东西
Class D<T> where T in {B,C}
这是由于一些奇怪的行为,我不负责 B 和 C 具有 A 中没有的通用方法,但是如果能够在 T 上的 D 中调用它们那就太好了。
注意:我无权访问 A、B 或 C 来编辑它们
Suppose I have the following class hierarchy:
Class A {...}
Class B : A {...}
Class C : A {...}
What I currently have is
Class D<T> where T : A {...}
but I'd like something of the form
Class D<T> where T in {B,C}
This is due to some odd behavior I'm not responsible for where B and C have common methods which aren't in A, but it would be nice to be able to call them in D on T.
Note: I don't have access to A,B or C to edit them
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
你需要为B和C中的公共方法定义一个接口(我们称之为Ibc),让B和C实现这个接口,然后你可以编写:
You need to define an interface for the common methods that are in B and C (lets call it Ibc), make B and C implement this interface, and then you can write:
首先,如果 B 和 C 有共同的方法,那么它们不共享接口就是一个设计缺陷。也就是说,即使无法访问 B 和 C,您也可以解决该问题。
可以创建一个通用接口。假设您有:
您可以创建一个公共接口:
并在 B 和 C 的派生类上使用它:
如果按原样获取 B 和 C 实例,您可能无法实现这一点,但如果您创建它们,则可以考虑。事实上,对于 B 和 C 的专门类,您可以使用接口而不是
D
。First, If B and C have common methods, it is a design flaw they don't share an interface. That said, you can fix that even without having access to B and C.
It is possible to create a common interface. Suppose you have:
You can create a common interface:
And use it on derived classes from B and C:
You may not be able to achieve that if you get B and C instances as is, but it can be considered if you create them. In fact, with specialized classes of B and C, you may use the interface instead of
D<T>
.这不是直接可能的。
正如其他人所建议的,您可以定义一个接口并在
B
和C
中实现它。如果这不是一个选项(例如,如果这些类超出了您的控制范围),我可能建议是这样的:首先,从一个抽象类开始,其中包含您可以使用任何
T
源自A
。然后假设您有一些B
和C
都存在的方法,但它们不属于A
的一部分。在D
中,您可以使这些抽象方法由子类实现:然后您可以从基类继承每个类型
B
和C
并且重写抽象方法以提供适当的功能:This isn't directly possible.
As others suggest, you could define an interface and implement it in both
B
andC
.If this isn't an option (e.g., if these classes are beyond your control), what I might suggest is this: first, start with an abstract class that includes all the functionality you can achieve with any
T
deriving fromA
. Then say you have some methods that exist for bothB
andC
that aren't a part ofA
. InD
you can make these abstract methods to be implemented by subclasses:Then you can inherit from the base class for each type
B
andC
and override the abstract method(s) to provide the appropriate functionality:B 和 C 实现相同的接口吗?这可能是更好的路线。
Do B and C implement the same interface? That may be a better route.
一些选项:
IdrivenFromA
,其中包含B
和C
的通用方法。从你的问题看来这是不可能的
D
中将T
转换为dynamic
并动态调用方法如果您可以使用 .Net 4,这是最简单的解决方案
D
测试中,您是否处理B
或C、转换和调用
将由编译器检查,并且可以从 .Net 2 开始
BD
的具体实现> 和C
,它们可以直接调用B
和C
中的方法。 (我自己没想到这一点)。仅当“用户源”知道它正在处理
B
或C
并且不使用抽象A
时才有效使用D
。相反,它应该使用DB
或DC
。但我认为情况就是如此,否则你不需要泛型。Some options:
IderivedFromA
that contain the common methods fromB
andC
.Looks like this is impossible from your question
D
castT
todynamic
and call the methods dynamicallyThe most easy solution, if you can use .Net 4
D
test if the you deal with anB
orC
, cast, and callWill be checked by the compiler, and is possible from .Net 2
D<T>
forB
andC
, these can call the methods fromB
andC
directly. (Didn't think of this one myself).Will only work if the "user-source" knows it is dealing with
B
orC
, and does not use the abstractA
to useD<A>
. Instead it should useDB
orDC
. But I think this is the case, otherwise you didn't need generics.C# 中的 where 约束不允许您指定多个类作为选择。
另外,如果您要指定多个包含位置,那么它们都必须满足。没有用于约束的 OR 逻辑。
以下是规范: http://msdn.microsoft.com/en-us/ Library/bb384067.aspx
Grzenio 的答案似乎适合您。将公共行为提取到 B 和 C 的公共接口中。然后您可以使用该接口作为约束。
The where constrain in C# does not allow you to specify multiple classes as a choice.
Also if you will specify multiple where contains, then they both has to be satisfied. There is no OR logic for constrain.
Here is specification: http://msdn.microsoft.com/en-us/library/bb384067.aspx
Answers from Grzenio seems right for you. Extract common behavior into the common interface for B and C. Then you can use that interface as a constrain.
由于您无权访问源代码,唯一真正的答案(除非您愿意因使用
动态
而失去安全性)是显式检查B< /code>/
C
并强制转换。Since you don't have access to the source, the only real answer (unless you are willing to lose safety by using
dynamic
) is explicitly check forB
/C
and cast.