Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在接口中声明成员函数_C#_Interface_Member - Fatal编程技术网

C# 在接口中声明成员函数

C# 在接口中声明成员函数,c#,interface,member,C#,Interface,Member,首先,我对C#很陌生。我想让一个接口声明一个成员函数,就像下面的代码一样 接口IMyInterface{ void MyAction(){ //根据函数()的输出执行操作 } 空函数(); } 这里的函数是纯虚拟的,应该由IMyInterface的子级实现。我可以使用抽象类而不是接口,但是我不能从其他类继承。。。例如,假设MyAction正在递归地搜索目录中的文件,并对找到的任何文件应用函数,以使我的示例更清晰 如何改变我的设计以克服接口不能实现类的限制 编辑:在C++中,我所做的就是使用模板

首先,我对C#很陌生。我想让一个接口声明一个成员函数,就像下面的代码一样

接口IMyInterface{
void MyAction(){
//根据函数()的输出执行操作
}
空函数();
}
这里的
函数
是纯虚拟的,应该由
IMyInterface
的子级实现。我可以使用抽象类而不是接口,但是我不能从其他类继承。。。例如,假设
MyAction
正在递归地搜索目录中的文件,并对找到的任何文件应用
函数
,以使我的示例更清晰

如何改变我的设计以克服接口不能实现类的限制

<>编辑:在C++中,我所做的就是使用模板,如

模板
静态无效动作(常数A&A){
//根据::Function()的输出执行操作
};
类MyClass{
空函数();
};

我想知道是否有一种优雅的方法可以使用C#中的接口来实现这一点。

接口不能实现任何行为,它们只是契约。如果要在定义契约时实现某些逻辑,可以使用抽象类。

直接处理此问题的唯一方法是使用抽象类,因为接口不能包含任何形式的“逻辑”,而仅仅是契约

然而,另一种选择是创建一个接口和一个静态类。然后,可以使用接口将逻辑放入扩展方法中

public interface IMyInterface {
    void Function();
}

public static class MyInterfaceExtensions {
    public static void MyAction(this IMyInterface object)
    {
       // use object.Function() as needed
    }
}

这里的主要缺点是类型较多,这会降低可维护性,并且缺乏可发现性。

您可以将
MyAction
定义为:

例如:

输出:


Hello World在接口中声明函数的接口(签名和返回类型),
然后创建一个定义用于实现该接口的抽象类,并在抽象类中实现一个基本的默认实现。然后,创建从抽象类继承的其他具体类,但在必要时,使用不同的实现重写抽象类基实现

接口是契约,不能包含实现

根据你的上述陈述:

我可以使用抽象类而不是接口,但这样我就不能从其他类继承

我相信您正在回答“为什么C#不支持多重继承”的问题


下面是一篇关于的CodeProject文章。您应该能够遵循此模式来实现C#的简单继承模型的解决方案

这类问题最好通过分离外部行为来解决
MyAction
在这种情况下,来自内部实现<代码>我的功能

这里的要点是理解什么应该是这个类和其他类之间的接口/契约的一部分,以及什么应该是该契约实现的一部分

在此,定义了该对象与其消费者之间的合同

interface IMyInterface
{
    void MyAction();
}
现在,一个实现这个接口的基类,它还强制执行一个特定的行为

abstract class BaseClass : IMyInterface
{
    public void MyAction()
    {
        // do some commmon action

        // call derived implementation to deal with the outcome
    }

    protected abstract void MyFunction();
}
最后是一个具体的实现,它以某种特定的方式处理MyFunction的结果

class ConcreteClass : BaseClass
{
    protected override void MyFunction()
    {
         // concrete implementation here
    }
}

为此目的。您需要定义抽象类。 您可以提供默认实现,也可以将实现留给派生类

如果派生类想要重写某些东西,它们总是可以这样做的。 这使他们能够灵活地使用base以及他们想要覆盖的更改。

在C#中,您没有多重继承。您可以通过使用合成来规避此限制

像这样定义界面(
函数
不需要在此处定义):

使用抽象
函数
声明抽象类并实现此接口:

public abstract class MyInterfaceBase : IMyInterface
{
    public void MyAction()
    {
        // Do stuff depending on the output of Function().
        Function();
    }

    protected abstract void Function();
}
从这个抽象类可以派生出一个具体的实现。这还不是您的“最终”类,但它将用于编写它

public class ConcreteMyInterface : MyInterfaceBase
{
    protected override void Function()
    {
        Console.WriteLine("hello");
    }
}
现在让我们来上你的“期末”作文课。它将派生自
SomeBaseClass
,并通过集成
ConcreteMyInterface
的功能来实现
IMyInterface

public class SomeBaseClass
{
}

public class MyComposedClass : SomeBaseClass, IMyInterface
{
    private readonly IMyInterface _myInterface = new ConcreteMyInterface();

    public void MyAction()
    {
        _myInterface.MyAction();
    }
}

更新

在C#中,您可以声明本地类。这更接近于多重继承,因为您可以派生组成类中的所有内容

public class MyComposedClass : SomeBaseClass, IMyInterface
{
    private readonly IMyInterface _myInterface = new ConcreteMyInterface();

    public void MyAction()
    {
        _myInterface.MyAction();
    }

    private class ConcreteMyInterface : MyInterfaceBase
    {
        protected override void Function()
        {
            Console.WriteLine("hello");
        }
    }
}

这是C#8.0的一个建议功能:


句号:接口永远不能定义实现。接口不能包含代码。它们只是定义了实现类必须提供的成员。您能确切地说明您想要做什么吗?我编辑了我的问题。很抱歉一开始就不清楚。更不用说“function()的输出”是
void
,这很难“依靠”来做事情。我知道。这就是我问题的重点,知道我的需要如何克服它。@vanna实际上,你从来没有问过问题。你只做了一些陈述。隐含的问题是,“如何在接口中定义方法的实现?”而(正确的)答案是,您不能。如果你有一个你想解决的问题,并且想知道如何解决它,那么描述一下这个问题,不要问如何在接口中定义方法。+1用于提及使用扩展方法在接口中实现功能这一经常被忽视的替代方法。@dasblinkenlight,但我担心一个全新的C#用户可能不理解扩展方法和真实实例方法之间的区别。如果您不理解它们的不同之处,可能会导致问题。@Servy-我同意-我不认为扩展方法应该是首选的设计方法。最好是在您需要在不能直接修改的类上扩展行为的情况下使用。我完全同意这一点
public abstract class MyInterfaceBase : IMyInterface
{
    public void MyAction()
    {
        // Do stuff depending on the output of Function().
        Function();
    }

    protected abstract void Function();
}
public class ConcreteMyInterface : MyInterfaceBase
{
    protected override void Function()
    {
        Console.WriteLine("hello");
    }
}
public class SomeBaseClass
{
}

public class MyComposedClass : SomeBaseClass, IMyInterface
{
    private readonly IMyInterface _myInterface = new ConcreteMyInterface();

    public void MyAction()
    {
        _myInterface.MyAction();
    }
}
public class MyComposedClass : SomeBaseClass, IMyInterface
{
    private readonly IMyInterface _myInterface = new ConcreteMyInterface();

    public void MyAction()
    {
        _myInterface.MyAction();
    }

    private class ConcreteMyInterface : MyInterfaceBase
    {
        protected override void Function()
        {
            Console.WriteLine("hello");
        }
    }
}
interface IA
{
    void M() { WriteLine("IA.M"); }
}

class C : IA { } // OK

IA i = new C();
i.M(); // prints "IA.M"`