有没有办法在C#中模拟多重继承?我知道没有,所以我需要你帮我找条路。
因此,我有一个项目,它有类,其中一种类型的类负责向管理器提供比较功能。因此,功能自然就是一个接口。
interface StringCompareString
{
string getName();
ErrorState compare_two_strings(string[] inputs, ref double[] similarities);
ErrorState compare_two_strings(string input1, string input2, ref double similarity);
}现在是这样的,比较函数有两种变体,一种获取一堆字符串,并以某种方式将它们全部相互比较,另一种只接收两个字符串,并只比较这两个。但是,我希望实现者(在我的团队中不做管理代码的人)收到第一个viriaty的默认compare_two_strings。
即此函数
注意:函数本身唯一重要的一点是,该函数必须引用compare_two_strings的简单版本。
ErrorState compare_two_strings(string[] inputs, ref double[] similarities)
{
similarities = new double[inputs.Count() * (inputs.Count() - 1) / 2];
int count = 0;
for (int i = 0; i < inputs.Count(); ++i)
{
for (int j = i + 1; j < inputs.Count(); ++j)
{
double finality = -1;
compare_two_strings(inputs[i], inputs[j], ref finality);
similarities[count] = finality;
++count;
}
}
}问题是我想在接口级别定义这个函数。然后是继承此接口的其他类,将此函数定义作为默认实现。而且这些类已经用完了继承的一次性票证。而且c#不允许在接口中定义任何函数,也不允许多重继承。该怎么办,该怎么办?
丑陋的方法是将函数实现复制粘贴到每个类中,这是非常糟糕的设计。
好的,谢谢大家的建议,我至少学到了很多新的流行语。最终的决定是使用组合,而不是在接口上。我将在StringCompareString已经继承的类上使用组合,这将释放抽象类的继承,而不是接口。
发布于 2014-01-21 05:15:37
如果你的实现者实际上只打算实现这两个方法中的一个,那么你就不应该把它们放在同一个接口中。
创建两个接口,每个方法一个接口;这样,如果有人只想提供两个方法中的一个方法的实现,就可以这样做。
提供两种类型,一种用于每个接口,具有该接口的“默认”实现。此类型作为Singleton可能是有意义的。这不是必须的,但它值得考虑。
如果消费者只需要其中一个方法,那么它可以只使用其中一个接口;如果它需要两个方法,那么它可以简单地接受两个对象。它可以碰巧是实现两个接口的单个实例,它可以是默认类型和自定义类型之一的副本,也可以是两个不同的自定义类型或其他任何类型。
如果重要的是传递可以做所有这些事情的某个单个实例(要么是为了与某个库交互,要么只是为了方便,如果消费者总是需要所有这些事情),那么只为单个方法创建接口,保留这个复合接口,然后创建一个实现所有方法的“大”接口的类,获取表示每个“小”接口的对象,然后将所有相关的方法调用分派给组合对象。
发布于 2014-01-21 05:17:43
在这种情况下,您通常会使用依赖项注入。
假设您有一个只提供字符串比较功能的类StringCompareString:
public sealed class StringCompareString
{
public ErrorState Compare(string[] inputs, ref double[] similarities)
{
// Implementation here...
}
public ErrorState Compare(string input1, string input2, ref double similarity)
{
// Implementation here...
}
}并且您有一个MyClass类,它想要比较字符串。然后,通过类的构造函数向类提供StringCompareString。例如:
public class MyClass
{
private StringCompareString comparer;
public MyClass(StringCompareString comparer)
{
if (comparer == null) throw new ArgumentNullException();
this.comparer = comparer;
}
public void DoSomething()
{
// Some code that uses the comparer:
this.comparer.Compare("String 1", "String 2", ...);
}
}您的MyClass现在有了对StringCompareString的依赖,并且您已经通过其构造函数注入了它。您可以很容易地将StringCompareString实现替换为不同的实现。而且任何类只需将StringCompareString作为构造函数参数即可使用它。不再复制代码。
发布于 2014-01-21 05:18:22
让需要这个功能的类接受这个功能作为构造函数参数,而不是让所有东西都从这个接口继承,怎么样?
示例
public class Foo : FooBase
{
//access StringCompareString functionality through this member instead
//of some base class
private readonly StringCompareString _comparer;
public Foo(StringCompareString comparer)
{
_comparer = comparer;
}
}https://stackoverflow.com/questions/21244191
复制相似问题