是否可以在C#中定义具有默认实现的接口?(这样我们就可以定义一个实现该接口的类,而无需实现该特定的默认方法).
我知道扩展方法(例如在此链接中解释).但这不是我的答案,因为有一个像下面的方法扩展,编译器仍然抱怨在MyClass中实现MyMethod:
public interface IMyInterface
{
string MyMethod();
}
public static class IMyInterfaceExtens
{
public static string MyMethod(this IMyInterface someObj)
{
return "Default method!";
}
}
public class MyClass: IMyInterface
{
// I want to have a default implementation of "MyMethod"
// so that I can skip implementing it here
}
Run Code Online (Sandbox Code Playgroud)
我问这个是因为(至少据我所知)可以用Java实现(见这里).
PS:拥有一个带有某种方法的抽象基类也不是我的答案,因为我们在C#中没有多重继承,它与接口的默认实现(如果可能!)不同.
Kon*_*dis 32
我开发游戏所以我经常希望为接口的所有实现提供通用功能,但同时允许每个实现也做自己的事情,就像子类的虚拟/覆盖方法一样.
我是这样做的:
public class Example
{
void Start()
{
WallE wallE = new WallE();
Robocop robocop = new Robocop();
// Calling Move() (from IRobotHelper)
// First it will execute the shared functionality, as specified in IRobotHelper
// Then it will execute any implementation-specific functionality,
// depending on which class called it. In this case, WallE's OnMove().
wallE.Move(1);
// Now if we call the same Move function on a different implementation of IRobot
// It will again begin by executing the shared functionality, as specified in IRobotHlper's Move function
// And then it will proceed to executing Robocop's OnMove(), for Robocop-specific functionality.
robocop.Move(1);
// The whole concept is similar to inheritence, but for interfaces.
// This structure offers an - admittedly dirty - way of having some of the benefits of a multiple inheritence scheme in C#, using interfaces.
}
}
public interface IRobot
{
// Fields
float speed { get; }
float position { get; set; }
// Implementation specific functions.
// Similar to an override function.
void OnMove(float direction);
}
public static class IRobotHelper
{
// Common code for all IRobot implementations.
// Similar to the body of a virtual function, only it always gets called.
public static void Move(this IRobot iRobot, float direction)
{
// All robots move based on their speed.
iRobot.position += iRobot.speed * direction;
// Call the ImplementationSpecific function
iRobot.OnMove(direction);
}
}
// Pro-Guns robot.
public class Robocop : IRobot
{
public float position { get; set; }
public float speed { get; set;}
private void Shoot(float direction) { }
// Robocop also shoots when he moves
public void OnMove(float direction)
{
Shoot(direction);
}
}
// Hippie robot.
public class WallE : IRobot
{
public float position { get; set; }
public float speed { get; set; }
// Wall-E is happy just moving around
public void OnMove(float direction) { }
}
Run Code Online (Sandbox Code Playgroud)
RBT*_*RBT 28
C#v8也将开始允许在接口中实现具体方法.这将允许您在更改将来实现的接口时不会破坏具体的实现类.
所以这样的东西在下一个语言版本中是可能的:
interface IA
{
void NotImplementedMethod();
void M() { WriteLine("IA.M"); } //method definition present in the interface
}
Run Code Online (Sandbox Code Playgroud)
请参阅此GitHub 问题#288.Mads Torgersen也在这个频道9视频中详细讨论了这个即将推出的功能.
注意:在编写此答案时,RTM状态的当前版本的C#语言是v7.
Ehs*_*jad 15
不,你不能在接口中编写方法的实现.
接口就像契约一样,因此从它继承的类型必须定义实现,如果你有一个场景需要一个带有默认实现的方法,那么你可以使你的类抽象并定义你想要的方法的默认实现.
例如:
public abstract class MyType
{
public string MyMethod()
{
// some implementation
}
public abstract string SomeMethodWhichDerivedTypeWillImplement();
}
Run Code Online (Sandbox Code Playgroud)
现在在Dervied班:
public class DerivedType : MyType
{
// now use the default implemented method here
}
Run Code Online (Sandbox Code Playgroud)
更新(C#8将支持此):
不是直接的,但你可以为接口定义一个扩展方法,然后像这样实现它
public interface ITestUser
{
int id { get; set; }
string firstName { get; set; }
string lastName { get; set; }
string FormattedName();
}
static class ITestUserHelpers
{
public static string FormattedNameDefault(this ITestUser user)
{
return user.lastName + ", " + user.firstName;
}
}
public class TestUser : ITestUser
{
public int id { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string FormattedName()
{
return this.FormattedNameDefault();
}
}
Run Code Online (Sandbox Code Playgroud)
编辑*重要的是,您实现的扩展方法和方法的命名方式不同,否则您可能会获得堆栈溢出.