#c# #constants #c#-8.0 #default-interface-member
Вопрос:
У нас есть интерфейс и реализующий класс:
pubic interface IStackContainer {
const string DefaultStack = "default";
}
public class StackContainer<T> : MyBaseStackContainer<T>, IStackContainer{
protected internal string Stack {
get { return Get(nameof(Stack), IInterface.DefaultStack); } //works fine
set { Set(nameof(Stack), DefaultStack, value); } //doesn't exist in the current context, why?
}
}
Почему я не могу получить доступ к константе в контейнере стека без «IInterface»?
PS: моя цель здесь-разместить константу где-нибудь вместо СтеккОнтейнера, чтобы иметь к ней легкий доступ. Если бы он был определен в StackContainer, я мог бы использовать его следующим образом: StackContainer.По умолчанию, но я думаю, что это не очень хорошее решение.
Комментарии:
1. Эти классы не наследуются один от другого. В моем случае, если бы IStackContainer был классом a, он работал бы нормально
2. @Progman Это другая проблема, и она не связана
3. Однако это одно и то же правило снова и снова — если вы хотите ссылаться на константу любого другого типа, независимо от того, какая связь наследования/реализации может существовать, вам всегда нужно ссылаться на нее через имя типа.
4. @Damien_The_Unbeliever … если только это не относится к базовому классу. Поскольку базовый класс похож на интерфейс, вполне разумно ожидать, что здесь они будут вести себя одинаково
5. Что ж, если вы хотите «унаследовать» от публичного интерфейса, вам нужно подождать несколько месяцев, прежде чем вы сможете безопасно получить доступ к любым постоянным участникам!
Ответ №1:
Тривиально, потому что так сказано в спецификации.
Я подозреваю, что это делается для того, чтобы избежать проблем, связанных с множественным наследованием. Считать:
interface IA
{
public const string DefaultStack = "default";
}
interface IB
{
}
class C : IA, IB
{
}
// Imagine this is allowed:
string stack = C.DefaultStack;
Представьте себе даже это IA
и IB
находитесь в разных сборках.
Теперь это кардинальное изменение , к которому нужно добавить const string DefaultStack = "..."
IB
, потому что это сделало C.DefaultStack
бы неоднозначным. Это фактически означает, что добавление любого поля const в интерфейс является критическим изменением, поскольку это может привести к конфликту с полем с тем же именем в каком-либо другом интерфейсе и нарушить какой-либо тип, который где-то реализует оба этих интерфейса.