Разрешение реализации интерфейса C#

Меня смущает следующий сценарий на С#, касающийся разрешения реализации интерфейса. Следующий код компилируется без ошибок:

interface IA
{
    void Method();
}

class CustomAttribute : Attribute { }

interface IB : IA
{
    [Custom]
    new void Method();
}

class BaseA : IA
{
    public void Method() => Console.WriteLine("Implementation in base");
}

class B: BaseA, IB
{
    new public void Method() => Console.WriteLine("Implementation in B");
}

class C : BaseA, IB
{ 
}

Интерфейс IA находится в библиотеке классов, к которой у нас нет доступа, в IB мы добавляем к методу собственный атрибут. Я ожидал, что Class C потребует другой реализации для Method, отличной от той, что в BaseA.

Мой вопрос: почему в class C реализация new Method для IB выбирается из BaseA, в то время как она отмечена new в IB?

Где в спецификации C# указано, как разрешить реализацию в таком случае?

Есть ли у этого процесса разрешения название?

Кстати, вы можете опустить оба ключевых слова new, и он все равно будет создаваться и работать (просто игнорируйте предупреждение о непреднамеренном сокрытии).

Dai 31.08.2024 09:59

@Дай Да, это правда. Спасибо за упоминание. Он по-прежнему компилируется без «нового» с предупреждениями.

Naser Asadi 31.08.2024 10:04

измените class C : BaseA, IB на class C : B, если вам нужна реализация с IB.

Luuk 31.08.2024 10:08

@Luuk Нет, мне просто интересно, почему компилируется класс C.

Naser Asadi 31.08.2024 10:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Есть ли у этого процесса разрешения название?

Это отображение интерфейса.

Во время сопоставления интерфейса компилятор всегда проверяет, есть ли в базовых классах реализация этого члена интерфейса.

(Выделено мной)

Отображение интерфейса для класса или структуры C находит реализацию для каждого члена каждого интерфейса, указанного в списке базовых классов C. Реализация конкретного члена интерфейса I.M, где I — это интерфейс, в котором объявлен член M, определяется путем проверки каждого класса или структуры S, начиная с C и повторяя для каждого последующего базового класса C, пока не будет найдено совпадение. ...

  • Если S содержит объявление явной реализации члена интерфейса, соответствующее I и M, то этот член является реализация I.M.

  • В противном случае, если S содержит объявление нестатического открытого члена, соответствующего M, то этот член является реализацией I.M. [...]

Для обычного публичного метода, такого как BaseA.Method, нет ничего, что мешало бы его сопоставлению как с IA.Method, так и с IB.Method.

Однако если бы BaseA.Method был явной реализацией интерфейса:

class BaseA : IA
{
    void IA.Method() => Console.WriteLine("Implementation in base");
}

Тогда его можно будет сопоставить только с IA.Method, и class C: BaseA, IB {} выдаст ошибку компилятора.

Другие вопросы по теме