【发布时间】:2015-05-14 13:29:56
【问题描述】:
编辑:更改以使代码更好地识别问题。
我正在调整蒙特卡罗模拟的性能,其中将 IComponent 转换为 IProposition 会导致瓶颈。我想出一个建筑师来移除铸件,但它没有按预期工作。
TryDo中的方法调用抛出编译错误? (参数类型'IProposition 不可分配给参数类型'T') 为什么? (IProposition 满足对 T 的约束)以及如何解决?
using System.Collections.Generic;
public interface IComponent<T> where T : IComponent<T>
{
HashSet<T> Inputs { get; }
}
public interface IProposition<T> : IComponent<T> where T : IComponent<T> { }
public interface IAnd<T> : IComponent<T> where T : IComponent<T> {}
class DoStuff<T> where T : IComponent<T>
{
private void DoIt(T component)
{
if (component is IAnd<T>)
foreach(T input in component.Inputs)
DoIt(input);
}
void TryDo(IProposition<T> proposition)
{
DoIt(proposition);
}
}
(我提出了一个单独的解决方案,它使用单独的类型 'TP' 来表示 IProposition - 但似乎是多余的,因为 IProposition 肯定是 IComposition 的子类)
【问题讨论】:
-
请在发布问题时告诉我们编译错误。
-
因为组件或介词都不是 T 类型(DoIt 期望的)。它们是 T 的 IComponent 和 T 的 IProposition 类型。您已经指定 T 是 T 的 IComponent 的事实不是编译器可以推断的。此外,T 的 IComponent 不是从 T 派生的。所以...是的。
-
您可以尝试 casting 组件和命题到 T 看看是否会引发任何无效的强制转换异常。毕竟你有一个复杂的模型。
-
说实话,您的模型非常令人困惑,
IComponent<T> where T : IComponent<T>{}或IProposition<T> : IComponent<T> where T : IComponent<T>{}的目的是什么?你确定这是你想要的模型吗? -
另外,你能至少展示一下这些接口在现实世界中的一些可能的用法吗?因为基本上这个模型强制每个组件成为它自己的一个组件或某个其他组件的一个组件。它有什么意义?它解决或防止了哪些领域问题?也许不限制
IComponent中的T参数(或限制为其他内容)以允许IComponent<IDataAccessService>等实现会更有用。
标签: c# generics inheritance constraints