van*_*nna 9 c# interface member
首先,我是C#的新手.我想有一个接口声明一个成员函数,如下面的代码片段
interface IMyInterface {
void MyAction() {
// do stuff depending on the output of function()
}
void Function();
}
Run Code Online (Sandbox Code Playgroud)
这里Function是纯粹的虚拟,应该由孩子们实施IMyInterface.我可以使用抽象类而不是接口,但后来我无法从其他类继承...例如,MyAction在递归搜索目录中的文件并应用于Function任何找到的文件以使我的示例清晰.
如何更改我的设计以克服接口无法实现类的约束?
编辑:在C++中,我要做的就是使用模板
template<class A>
static void MyAction(const A& a) {
// do stuff depending on the output of A::Function()
};
class MyClass {
void Function();
};
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一种优雅的方式来使用C#中的接口来做到这一点.
Ree*_*sey 11
直接处理这个问题的唯一方法是使用抽象类,因为接口不能包含任何形式的"逻辑",而只是一个契约.
然而,一种替代方案是创建接口和静态类.然后,您可以使用界面将逻辑放在扩展方法中.
public interface IMyInterface {
void Function();
}
public static class MyInterfaceExtensions {
public static void MyAction(this IMyInterface object)
{
// use object.Function() as needed
}
}
Run Code Online (Sandbox Code Playgroud)
这里的主要缺点是更多类型,这降低了可维护性,并且缺乏可发现性.
Oli*_*bes 10
在C#中,您没有多重继承.您可以通过使用合成来规避此限制.
像这样定义你的界面(Function这里不需要定义):
public interface IMyInterface
{
void MyAction();
}
Run Code Online (Sandbox Code Playgroud)
使用抽象声明一个抽象类Function并实现此接口:
public abstract class MyInterfaceBase : IMyInterface
{
public void MyAction()
{
// Do stuff depending on the output of Function().
Function();
}
protected abstract void Function();
}
Run Code Online (Sandbox Code Playgroud)
从这个抽象类中,您可以派生出具体的实现.这还不是你的"最终"类,但它将被用来组成它.
public class ConcreteMyInterface : MyInterfaceBase
{
protected override void Function()
{
Console.WriteLine("hello");
}
}
Run Code Online (Sandbox Code Playgroud)
现在让我们来到你的"最后",写作课.它将通过集成以下功能来SomeBaseClass实现和实现:IMyInterfaceConcreteMyInterface
public class SomeBaseClass
{
}
public class MyComposedClass : SomeBaseClass, IMyInterface
{
private readonly IMyInterface _myInterface = new ConcreteMyInterface();
public void MyAction()
{
_myInterface.MyAction();
}
}
Run Code Online (Sandbox Code Playgroud)
UPDATE
在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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以定义MyAction为扩展方法:
public interface IMyInterface
{
void Function();
}
public static class MyInterfaceExtensions
{
public static void MyAction(this IMyInterface obj)
{
obj.Function();
}
}
Run Code Online (Sandbox Code Playgroud)
例:
public class HelloWorld : IMyInterface
{
public void Function()
{
Console.WriteLine("Hello World");
}
public static void Main(string[] args)
{
new HelloWorld().MyAction();
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Hello World