接口的C#OOP限制正在扼杀我的项目

时间:2014-01-20 21:09:56

标签: c# oop inheritance interface

有没有办法在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已经继承的类上使用组合,这将释放抽象类而不是接口的继承。

3 个答案:

答案 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;
    }

}