Не удается скомпилировать метод интерфейса C# по умолчанию
В 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
не реализует интерфейс). Но он не видит член интерфейса по умолчанию как общедоступный метод класса, реализующего интерфейс.
Я что-то упустил или что-то сломалось?
2 ответа
Ну, метод интерфейса по умолчанию принадлежит интерфейсу, а не классу, который его реализует; так что у вас есть две возможности:
В ролях:
Console.WriteLine(((ITest)xxx).GetItNow()));
Изменение декларации (желательно; MyClass
является реализация деталей, часто это зависимость;ITest
- дело только в контракте):
ITest xxx = new MyClass { MyInt = 5 };
// xxx is ITest, so xxx.GetItNow() is legal now
Console.WriteLine(xxx.GetItNow());
/questions/51942767/ne-udaetsya-skompilirovat-metod-interfejsa-c-po-umolchaniyu/51942775#51942775 - отличный и четкий ответ, я пытался сделать то же самое с этой новой функцией, но компилятор остановил его. Теперь я знаю, почему.
Если вы намерены пометить какой-либо класс интерфейсом и привязать к нему некоторые функции. Я использовал методы расширения самого интерфейса для достижения этого эффекта. Единственным недостатком является то, что в настоящее время поддерживаются только функции, а не свойства.
public interface ITest
{
int MyInt { get; set; }
}
public static class ITestExtensions
{
public static int GetItNow(this ITest self)
{
return self.MyInt * 2;
}
}