2

We have the interface and the implementing class:

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?
    }
}

Why can't I access the constant in the StackContainer without "IInterface."?

PS: my purpose here is to place the const somewhere instead of StackContainer in order to have easy access to it. If it was defined in the StackContainer I could use it like this: StackContainer.DefaultStack, but it isn't a good decision, I think.

canton7
  • 37,633
  • 3
  • 64
  • 77
Eugene Maksimov
  • 1,504
  • 17
  • 36
  • These classes are not inherited one from another. In my case if IStackContainer was an a class it would work fine – Eugene Maksimov Jul 14 '21 at 10:03
  • @Progman That's a different problem, and is not related – canton7 Jul 14 '21 at 10:04
  • It's the same rule over and again though - if you want to reference a constant in *any* other type, no matter what inheritance/implementation relationship may exist, you always have to reference it via the type's name. – Damien_The_Unbeliever Jul 14 '21 at 10:06
  • @Damien_The_Unbeliever ... unless it's in a base class. Since a base class is similar to an interface, it's not unreasonable to expect that they behave the same way here – canton7 Jul 14 '21 at 10:06
  • Well, if you want to "inherit" from a **pubic** interface, you need to wait several months before you can safely access any constant members! – Vector Sigma Aug 10 '21 at 11:17

1 Answers1

8

Trivially, because that's what the spec says.

I suspect this is to avoid the problems which come with multiple inheritance. Consider:

interface IA
{
    public const string DefaultStack = "default";
}

interface IB
{
}

class C : IA, IB
{
}

// Imagine this is allowed:
string stack = C.DefaultStack;

Imagine even that IA and IB are in different assemblies.

It's now a breaking change to add const string DefaultStack = "..." to IB, because that would make C.DefaultStack ambiguous. That effectively means that adding any const field to an interface is a breaking change, because that might conflict with a field of the same name in some other interface, and break some type which implements both of those interfaces somewhere.

canton7
  • 37,633
  • 3
  • 64
  • 77