有没有办法在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);
}
现在这里是交易,比较函数有两种变体,其中一种获取一串字符串,并且应该以某种方式将它们相互比较,而另一种只接收两个字符串,并且应该比较这两个。但是我希望实现者(我的组中没有管理代码的人)接收第一个病毒的默认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已经继承的类上使用组合,这将释放抽象类而不是接口的继承。
答案 0 :(得分:2)
如果您打算实际上只打算实现这两种方法中的一种,那么您不应该将它们放在同一个界面中。
创建两个接口,每个接口一个;这样,如果有人想要提供他们可以实现的两种方法之一的实现。
提供两种类型,每种接口一种,具有该接口的“默认”实现。这种类型的单身人士可能有意义。它不会需要,但值得考虑。
如果只需要其中一种方法,那么消费者只能使用其中一种界面;它需要两种方法然后它可以简单地接受两个对象。它可能恰好是实现两个接口的单个实例,它可以是默认类型的副本,也可以是自定义类型,两种不同自定义类型或其他类型的副本。
如果传递一些某事的单个实例是很重要的,这些实例可以做所有这些事情(必要时,为了与某些库交互,或者只是为了方便,如果消费者总是需要所有这些然后创建仅用于单个方法的接口,保留此复合接口,然后创建一个实现“大”接口的类将所有方法,接受表示每个“较小”接口的对象,然后只是将所有相关方法调用分派给组合对象。
答案 1 :(得分:1)
在这种情况下,您通常使用依赖注入。
比如说,您有一个类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
作为构造函数参数来使用它。不再需要复制代码。
答案 2 :(得分:0)
如果不是让所有内容都继承自此接口,那么您是否需要使用此功能的类接受此功能作为构造函数参数?
实施例
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;
}
}