Compilation Error: "The Modifier 'Public' Is Not Valid for This Item" While Explicitly Implementing the Interface

Compilation Error: The modifier 'public' is not valid for this item while explicitly implementing the interface

When using explicit implementation of an interface, the members are forced to something more restricted than private in the class itself. And when the access modifier is forced, you may not add one.

Likewise, in the interface itself, all members are public. If you try to add a modifier inside an interface you will get a similar error.

Why are explicit members (very) private? Consider:

interface I1 { void M(); }
interface I2 { void M(); }

class C : I1, I2
{
void I1.M() { ... }
void I2.M() { ... }
}

C c = new C();
c.M(); // Error, otherwise: which one?
(c as I1).M(); // Ok, no ambiguity.

If those methods were public, you would have a name-clash that cannot be resolved by the normal overload rules.

For the same reason you cannot even call M() from inside a class C member. You will have to cast this to a specific interface first to avoid the same ambiguity.

class C : I1, I2
{
...
void X()
{
M(); // error, which one?
((I1)this).M(); // OK
}
}

Inherited Interface's Method Can't Be Explicitly Declare as Public

I have this explicit message from Resharper :
"The modifier 'public' is not valid for explicit interface implementation."

But you can do that :

class DuplicateInterfaceClass : MyInterface1, MyInterface2
{
public void DuplicateMethod()
{
Console.WriteLine("DuplicateInterfaceClass.DuplicateMethod");
}

string MyInterface1.P
{ get { return "DuplicateInterfaceClass.P"; } }

string MyInterface2.P()
{ return "DuplicateInterfaceClass.P()"; }

public string P()
{ return ((MyInterface2)this).P(); }
}

Why can't I explicitly set the access level for GetEnumerator?

Normally when you implement an interface, you must specify public for the methods and properties. In this case, not only do those methods and properties contribute towards implementing the interface, they are also just like any other regular method or property. Being able to add public to them makes sense. However, the IEnumerator.GetEnumerator you've declared here is a bit special.

This is an explicit interface implementation of IEnumerable.GetEnumerator. Just in case you didn't know, this is the non-generic (by which I mean, returns a non-generic IEnumerator) version of IEnumerable<T>.GetEnumerator, declared in IEnumerable (not to be confused with IEnumerable<T>!). Since IEnumerable<T> inherits from IEnumerable, you are required to implement both when implementing IEnumerable<T>.

If you didn't use an explicit interface implementation here, you would have two methods with the same name, both accepting no parameters, with only the return value different:

public IEnumerator<int> GetEnumerator()
{
...
}

public IEnumerator GetEnumerator() // CS0111
{
...
}

This is not allowed. This is where explicit interface implementation comes in. If you declare the non-generic GetEnumerator by prefixing the name of the interface where it comes from:

IEnumerator IEnumerable.GetEnumerator()
{
...
}

Then this method is only accessible on an expression with a type of IEnumerable. For example, let's say your collection is called MyCollection.

MyCollection myCollection = ...;
// this accesses the *generic* GetEnumerator, the non-generic one is not accessible
myCollection.GetEnumerator()

// the non generic one is only accessible if you cast to IEnumerable
((IEnumerable)myCollection).GetEnumerator()

Even if in the same class, you can't access the non-generic GetEnumerator without casting to IEnumerable first. Do you see how this is somewhat different from what private usually means? None of the access modifiers can really express the accessibility of explicit interface implementations, to be honest.

Nested Interface & Abstract Implementation Class

The problem isn't with the nesting - it's with explicit interface implementation. If you change your "working" example to use:

public abstract void SomeInterface.Method()

you'll see the same problem. You should be able to use implicit interface implementation with a nested interface easily:

public abstract class B : A.InnerInterface
{
public abstract void Method();
}

public class C : B
{
public override void Method()
{
System.Console.WriteLine("C::A.InnerInterface.Method()");
}
}

... and if you want to use explicit interface implementation, it should work in the same way for a nested interface as a non-nested one. But you don't write public on explicit interface implementations, and they can't be abstract either (IIRC).

Explicit interface derivation: private method accessible as public one

With reference to The C# Language Specification, 13.4.1 Explicit interface member implementations

It is a compile-time error for an explicit interface member implementation to include access modifiers, and it is a compile-time error to include the modifiers abstract, virtual, override, or static.

Such methods have to be accessed via a reference to the interface and they have the same access level as the interface itself (either public or internal).

The modifier 'static' is not valid for this item / Static interface error in c#

You can't do it. It should be

   public interface ICache
{
//Get item from cache
object Get(string pName);
//Check an item exist in cache
bool Contains(string pName);
//Add an item to cache
void Add(string pName, object pValue);
//Remove an item from cache
void Remove(string pName);
}

Check out Why Doesn't C# Allow Static Methods to Implement an Interface?

Also Eric Lippert wrote a cool article series called

  • Calling static methods on type parameters is illegal, part one, part two

How to call method which is explicitly implemented

Explicit interfaces methods can only be accessed through the interface and not through the class that implement them.

In your code, you can cast an instance of your class to the interface and then reference the method/property that was explicitly defined.

MSDN Link on Explicit Interface:
http://msdn.microsoft.com/en-us/library/ms173157%28v=vs.100%29.aspx

Another question asking a similar thing:
Compilation Error: "The modifier 'public' is not valid for this item" while explicitly implementing the interface

How to satisfy the compiler when only partially implementing an interface with an abstract class?

Just declare Swim as abstract and don't try to use explicit interface declaration for it (i.e. remove IFish).

abstract class WalkingFishCommon : IFish
{
public bool CanWalk { get { return true; } }
public abstract bool Swim();
}

C#8 feature used in framework 4.7.2 does NOT cause build error in Visual Studio, but does on TFS

Someone probably changed the project settings in the past (when it was a Visual Studio 2017 project) to enable support for an earlier language version (e.g. C# 7).

Check the ".csproj" file for <LangVersion>latest</LangVersion> or <LangVersion>8.0</LangVersion> and remove it if you find it.

VS2019 uses the selected .Net framework version to determine the supported C# language version unless it's overridden with the above.

For VS2017 you could select to use the latest language version via the project settings (without editing the .CSProj file) and if you did that, after upgrading to VS2019 it would allow the use of C#8...

We hit exactly the same issue as you because of that sequence of events. We have now decided that using <LangVersion>latest</LangVersion> is no longer safe, since after upgrading to a newer version of Visual Studio, you could end up accidentally enabling a later version of the C# language than you intended.



Related Topics



Leave a reply



Submit