C#8.0有一个新功能,可以在接口上为方法添加默认实现。要么我做错了什么,要么这个功能没有像宣传的那样工作。(我猜是前者。(
我创建了一个新的.NET Core 3.1控制台应用程序,代码如下:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var xxx = new MyClass { MyInt = 5 };
Console.WriteLine(xxx.GetItNow());
}
}
public interface ITest
{
int MyInt { get; set; }
int GetItNow() => MyInt * 2;
}
public class MyClass : ITest
{
public int MyInt { get; set; }
}
}
Console.WriteLine(xxx.GetItNow()));
语句未编译,因为
Myclass不包含"GetItNow(("的定义。。。
因此,编译器对MyClass
没有显式引用GetItNow()
这一事实感到满意(它并不抱怨MyClass
没有实现接口(。但它并不将默认接口成员视为实现接口的类的公共方法。
我是错过了什么,还是什么东西坏了?
好吧,接口默认方法属于界面,而不是实现它的类;所以你有两种可能性:
铸件:
Console.WriteLine(((ITest)xxx).GetItNow()));
声明更改(更可取;MyClass
是实现细节,通常是dependency;ITest
-合同是唯一重要的东西(:
ITest xxx = new MyClass { MyInt = 5 };
// xxx is ITest, so xxx.GetItNow() is legal now
Console.WriteLine(xxx.GetItNow());
https://stackoverflow.com/a/61717913/779967是一个非常好且清晰的答案,我曾试图用这个新功能做同样的事情,但被编译器阻止了。现在我知道为什么了。
如果你的意图是用接口标记某个类,并为其附加一些功能。我一直在接口本身上使用扩展方法来实现这种效果。唯一的缺点是目前只支持函数而不支持属性。
public interface ITest
{
int MyInt { get; set; }
}
public static class ITestExtensions
{
public static int GetItNow(this ITest self)
{
return self.MyInt * 2;
}
}