首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >接口的C# OOP限制正在扼杀我的项目

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

Stack Overflow用户
提问于 2014-01-21 05:09:56
回答 3查看 320关注 0票数 1

有没有办法在C#中模拟多重继承?我知道没有,所以我需要你帮我找条路。

因此,我有一个项目,它有类,其中一种类型的类负责向管理器提供比较功能。因此,功能自然就是一个接口。

代码语言:javascript
复制
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的简单版本。

代码语言:javascript
复制
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已经继承的类上使用组合,这将释放抽象类的继承,而不是接口。

EN

回答 3

Stack Overflow用户

发布于 2014-01-21 05:15:37

如果你的实现者实际上只打算实现这两个方法中的一个,那么你就不应该把它们放在同一个接口中。

创建两个接口,每个方法一个接口;这样,如果有人只想提供两个方法中的一个方法的实现,就可以这样做。

提供两种类型,一种用于每个接口,具有该接口的“默认”实现。此类型作为Singleton可能是有意义的。这不是必须的,但它值得考虑。

如果消费者只需要其中一个方法,那么它可以只使用其中一个接口;如果它需要两个方法,那么它可以简单地接受两个对象。它可以碰巧是实现两个接口的单个实例,它可以是默认类型和自定义类型之一的副本,也可以是两个不同的自定义类型或其他任何类型。

如果重要的是传递可以做所有这些事情的某个单个实例(要么是为了与某个库交互,要么只是为了方便,如果消费者总是需要所有这些事情),那么只为单个方法创建接口,保留这个复合接口,然后创建一个实现所有方法的“大”接口的类,获取表示每个“小”接口的对象,然后将所有相关的方法调用分派给组合对象。

票数 2
EN

Stack Overflow用户

发布于 2014-01-21 05:17:43

在这种情况下,您通常会使用依赖项注入。

假设您有一个只提供字符串比较功能的类StringCompareString

代码语言:javascript
复制
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。例如:

代码语言:javascript
复制
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作为构造函数参数即可使用它。不再复制代码。

票数 1
EN

Stack Overflow用户

发布于 2014-01-21 05:18:22

让需要这个功能的类接受这个功能作为构造函数参数,而不是让所有东西都从这个接口继承,怎么样?

示例

代码语言:javascript
复制
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;
    }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21244191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档