Han*_*mpf 1 c# interface multiple-inheritance parameter-passing abstract
考虑C#中的以下结构:
interface I1
interface I2
abstract class A
- class A1 : A
- class A11 : A1, I1
- class A12 : A1, I2
- class A2 : A
- class A21 : A2, I1
- class A22 : A2, I2
Run Code Online (Sandbox Code Playgroud)
现在我有一个B类,它在构造函数中接受一个参数.该参数必须是以某种方式从A派生并实现接口I2的类,即它可以是类型A12或A22,但不是A11或A21.我该如何定义该参数?此外,我想稍后将参数存储为B中的属性(以供以后使用).
我无法将A重新定义为接口,因为它提供了许多虚拟方法.我也不能跳过树状继承方案,因为A1和A2提供了许多在别处使用的特定方法(不在B中).所以,我需要在B中处理的是来自A和I2的东西.
这对你有用吗?
class B<T> where T : A, I2
{
public B(T parameter)
{
this.Property = parameter;
}
public T Property { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
我该如何定义该参数?
基本上你不能.不在构造函数中.
你最接近的可能是创建一个返回B的静态泛型方法:
public static B CreateInstance<T>(T item) where T : A, I2
Run Code Online (Sandbox Code Playgroud)
您不能在构造函数中执行此操作,因为构造函数不能是通用的.
然而,然后如果你需要存储该值,则需要选择有类型的字段A或I2,并投当您需要.
当然,您可以B根据Enigmativity的答案制作通用 - 但这可能会在其他地方产生其他影响.如果你想要一个非泛型的B,你可能有两个:
public abstract class B
{
// Common operations which don't depend on the constructor parameter
}
public class B<T> : B where T : A, I2
{
public B(T item)
{
}
}
Run Code Online (Sandbox Code Playgroud)
当然,这开始变得相当复杂.
或者,您可以跳过编译时检查,并在执行时检查:
public class B
{
private readonly A item;
public B(A item)
{
if (!(item is I2))
{
throw new ArgumentException("...");
}
this.item = item;
}
}
Run Code Online (Sandbox Code Playgroud)
虽然编译时安全性是一般较好,这可能是因为它不值得你需要在这种情况下要经过额外的铁圈.这实际上取决于你对这种类型做了什么.
| 归档时间: |
|
| 查看次数: |
970 次 |
| 最近记录: |