abstract class 'does not implement interface member ...'

  • Thread starter Ben Voigt [C++ MVP]
  • Start date
B

Ben Voigt [C++ MVP]

I get
C:\Programming\LTM\devtools\UselessJunkForDissassembly\Class1.cs(360,27):
error CS0535: 'UselessJunkForDissassembly.InvocableInternals' does not
implement interface member
'UselessJunkForDissassembly.IInvocableInternals.OperationValidate(string)'
C:\Programming\LTM\devtools\UselessJunkForDissassembly\Class1.cs(360,27):
error CS0535: 'UselessJunkForDissassembly.InvocableInternals' does not
implement interface member
'UselessJunkForDissassembly.IInvocableInternals.ProxiedOperation'

when compiling:
public interface IInvocable
{
object Operation { get; }
}
internal interface IInvocableInternals : IInvocable
{
bool OperationValidate(string args);
string ProxiedOperation { get; }
}
public abstract class InvocableInternals : IInvocableInternals
{
public object Operation { get { return ProxiedOperation; } }
}

But, I already knew the class didn't implement those functions. That's why
it is *abstract*. Please note that I've replaced all complicated types with
object or string to make a minimal reproduction. I don't want my internal
functions exposed publicly, I can't hide InvocableInternals because public
classes inherit from it, and I don't want to use a forwarder because, I'm
convinced that the JIT wouldn't be able to inline it.
Why isn't it allowed to just implement
"IInvocableInternals.OperationValidate" in the most derived class?
 
N

Nicholas Paldino [.NET/C# MVP]

Ben,

According to the language specification:

20.4.5 Abstract classes and interfaces

1. Like a non-abstract class, an abstract class must provide implementations
of all members of the interfaces that are listed in the base class list of
the class.

Or are you asking why the language specification is this way?
 
B

Ben Voigt [C++ MVP]

Nicholas Paldino said:
Ben,

According to the language specification:

20.4.5 Abstract classes and interfaces

1. Like a non-abstract class, an abstract class must provide
implementations of all members of the interfaces that are listed in the
base class list of the class.

Ok, but since the interface is internal, I should be allowed to:

public interface IInvocable
{
object Operation { get; }
}

internal interface IInvocableInternals : IInvocable
{
bool OperationValidate(string args);

string ProxiedOperation { get; }
}

public abstract class InvocableInternals : IInvocableInternals
{
internal abstract string ProxiedOperation { get; }
public object Operation { get { return ProxiedOperation; } }
}
Or are you asking why the language specification is this way?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
I get
C:\Programming\LTM\devtools\UselessJunkForDissassembly\Class1.cs(360,27):
error CS0535: 'UselessJunkForDissassembly.InvocableInternals' does not
implement interface member
'UselessJunkForDissassembly.IInvocableInternals.OperationValidate(string)'
C:\Programming\LTM\devtools\UselessJunkForDissassembly\Class1.cs(360,27):
error CS0535: 'UselessJunkForDissassembly.InvocableInternals' does not
implement interface member
'UselessJunkForDissassembly.IInvocableInternals.ProxiedOperation'

when compiling:
public interface IInvocable
{
object Operation { get; }
}
internal interface IInvocableInternals : IInvocable
{
bool OperationValidate(string args);
string ProxiedOperation { get; }
}
public abstract class InvocableInternals : IInvocableInternals
{
public object Operation { get { return ProxiedOperation; } }
}

But, I already knew the class didn't implement those functions. That's
why it is *abstract*. Please note that I've replaced all complicated
types with object or string to make a minimal reproduction. I don't want
my internal functions exposed publicly, I can't hide InvocableInternals
because public classes inherit from it, and I don't want to use a
forwarder because, I'm convinced that the JIT wouldn't be able to inline
it.
Why isn't it allowed to just implement
"IInvocableInternals.OperationValidate" in the most derived class?
 
N

Nicholas Paldino [.NET/C# MVP]

Ben,

I see what you are getting at now. This is one of the things that has
always frustrated me as well. Honestly, I never saw any pitfalls to
allowing this, since abstract methods are the same as virtual methods
anyways when seen from the derived class on.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
Nicholas Paldino said:
Ben,

According to the language specification:

20.4.5 Abstract classes and interfaces

1. Like a non-abstract class, an abstract class must provide
implementations of all members of the interfaces that are listed in the
base class list of the class.

Ok, but since the interface is internal, I should be allowed to:

public interface IInvocable
{
object Operation { get; }
}

internal interface IInvocableInternals : IInvocable
{
bool OperationValidate(string args);

string ProxiedOperation { get; }
}

public abstract class InvocableInternals : IInvocableInternals
{
internal abstract string ProxiedOperation { get; }
public object Operation { get { return ProxiedOperation; } }
}
Or are you asking why the language specification is this way?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
I get
C:\Programming\LTM\devtools\UselessJunkForDissassembly\Class1.cs(360,27):
error CS0535: 'UselessJunkForDissassembly.InvocableInternals' does not
implement interface member
'UselessJunkForDissassembly.IInvocableInternals.OperationValidate(string)'
C:\Programming\LTM\devtools\UselessJunkForDissassembly\Class1.cs(360,27):
error CS0535: 'UselessJunkForDissassembly.InvocableInternals' does not
implement interface member
'UselessJunkForDissassembly.IInvocableInternals.ProxiedOperation'

when compiling:
public interface IInvocable
{
object Operation { get; }
}
internal interface IInvocableInternals : IInvocable
{
bool OperationValidate(string args);
string ProxiedOperation { get; }
}
public abstract class InvocableInternals : IInvocableInternals
{
public object Operation { get { return ProxiedOperation; } }
}

But, I already knew the class didn't implement those functions. That's
why it is *abstract*. Please note that I've replaced all complicated
types with object or string to make a minimal reproduction. I don't
want my internal functions exposed publicly, I can't hide
InvocableInternals because public classes inherit from it, and I don't
want to use a forwarder because, I'm convinced that the JIT wouldn't be
able to inline it.
Why isn't it allowed to just implement
"IInvocableInternals.OperationValidate" in the most derived class?
 
B

Ben Voigt [C++ MVP]

Nicholas Paldino said:
Ben,

I see what you are getting at now. This is one of the things that has
always frustrated me as well. Honestly, I never saw any pitfalls to
allowing this, since abstract methods are the same as virtual methods
anyways when seen from the derived class on.

I've never understood this whole requirement about "type less visible than
....". Why can't I return an internal interface from a protected member
function, or vice versa? There are some perfectly valid combinations that
just can't be used currently. At most, the compiler should generate a
warning, definitely not an error.
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
Nicholas Paldino said:
Ben,

According to the language specification:

20.4.5 Abstract classes and interfaces

1. Like a non-abstract class, an abstract class must provide
implementations of all members of the interfaces that are listed in the
base class list of the class.

Ok, but since the interface is internal, I should be allowed to:

public interface IInvocable
{
object Operation { get; }
}

internal interface IInvocableInternals : IInvocable
{
bool OperationValidate(string args);

string ProxiedOperation { get; }
}

public abstract class InvocableInternals : IInvocableInternals
{
internal abstract string ProxiedOperation { get; }
public object Operation { get { return ProxiedOperation; } }
}
Or are you asking why the language specification is this way?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I get
C:\Programming\LTM\devtools\UselessJunkForDissassembly\Class1.cs(360,27):
error CS0535: 'UselessJunkForDissassembly.InvocableInternals' does not
implement interface member
'UselessJunkForDissassembly.IInvocableInternals.OperationValidate(string)'
C:\Programming\LTM\devtools\UselessJunkForDissassembly\Class1.cs(360,27):
error CS0535: 'UselessJunkForDissassembly.InvocableInternals' does not
implement interface member
'UselessJunkForDissassembly.IInvocableInternals.ProxiedOperation'

when compiling:
public interface IInvocable
{
object Operation { get; }
}
internal interface IInvocableInternals : IInvocable
{
bool OperationValidate(string args);
string ProxiedOperation { get; }
}
public abstract class InvocableInternals : IInvocableInternals
{
public object Operation { get { return ProxiedOperation; } }
}

But, I already knew the class didn't implement those functions. That's
why it is *abstract*. Please note that I've replaced all complicated
types with object or string to make a minimal reproduction. I don't
want my internal functions exposed publicly, I can't hide
InvocableInternals because public classes inherit from it, and I don't
want to use a forwarder because, I'm convinced that the JIT wouldn't be
able to inline it.
Why isn't it allowed to just implement
"IInvocableInternals.OperationValidate" in the most derived class?
 
N

Nicholas Paldino [.NET/C# MVP]

Ben,

Well, that's a different story. The issue with me is that abstract
members can not implement interface members.

However, saying that a protected member can not expose an internal
member is justified, because with a protected member, the possibility exists
that the protected member will be accessed outside of the assembly, which
would violate the internal member's visibility.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
Nicholas Paldino said:
Ben,

I see what you are getting at now. This is one of the things that has
always frustrated me as well. Honestly, I never saw any pitfalls to
allowing this, since abstract methods are the same as virtual methods
anyways when seen from the derived class on.

I've never understood this whole requirement about "type less visible than
...". Why can't I return an internal interface from a protected member
function, or vice versa? There are some perfectly valid combinations that
just can't be used currently. At most, the compiler should generate a
warning, definitely not an error.
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
in message Ben,

According to the language specification:

20.4.5 Abstract classes and interfaces

1. Like a non-abstract class, an abstract class must provide
implementations of all members of the interfaces that are listed in the
base class list of the class.

Ok, but since the interface is internal, I should be allowed to:

public interface IInvocable
{
object Operation { get; }
}

internal interface IInvocableInternals : IInvocable
{
bool OperationValidate(string args);

string ProxiedOperation { get; }
}

public abstract class InvocableInternals : IInvocableInternals
{
internal abstract string ProxiedOperation { get; }
public object Operation { get { return ProxiedOperation; } }
}


Or are you asking why the language specification is this way?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I get
C:\Programming\LTM\devtools\UselessJunkForDissassembly\Class1.cs(360,27):
error CS0535: 'UselessJunkForDissassembly.InvocableInternals' does not
implement interface member
'UselessJunkForDissassembly.IInvocableInternals.OperationValidate(string)'
C:\Programming\LTM\devtools\UselessJunkForDissassembly\Class1.cs(360,27):
error CS0535: 'UselessJunkForDissassembly.InvocableInternals' does not
implement interface member
'UselessJunkForDissassembly.IInvocableInternals.ProxiedOperation'

when compiling:
public interface IInvocable
{
object Operation { get; }
}
internal interface IInvocableInternals : IInvocable
{
bool OperationValidate(string args);
string ProxiedOperation { get; }
}
public abstract class InvocableInternals : IInvocableInternals
{
public object Operation { get { return ProxiedOperation; } }
}

But, I already knew the class didn't implement those functions.
That's why it is *abstract*. Please note that I've replaced all
complicated types with object or string to make a minimal
reproduction. I don't want my internal functions exposed publicly, I
can't hide InvocableInternals because public classes inherit from it,
and I don't want to use a forwarder because, I'm convinced that the
JIT wouldn't be able to inline it.
Why isn't it allowed to just implement
"IInvocableInternals.OperationValidate" in the most derived class?
 
P

Peter Duniho

Ok, but since the interface is internal, I should be allowed to:

public interface IInvocable
{
object Operation { get; }
}

internal interface IInvocableInternals : IInvocable
{
bool OperationValidate(string args);

string ProxiedOperation { get; }
}

public abstract class InvocableInternals : IInvocableInternals
{
internal abstract string ProxiedOperation { get; }
public object Operation { get { return ProxiedOperation; } }
}

I'm not entirely clear about what you're asking about.

When I tried to compile the code you posted above, I got two errors, both
expected (at least to me):

OperationValidate was undefined, and
ProxiedOperation was not public

Since you provided no definition for OperationValidate, the error is not
surprising. This error is easily addressed by including an abstract
definition for the method in InvocableInternals. I don't see any problem
at all doing that.

Since interface members are required to be public, the second error is not
surprising either. This error is easily addressed by changing the
protection for ProxiedOperation so that it's public. The interface itself
is internal, so if you are concerned that InvocableInternals is public and
you don't want external code getting at the interface method
ProxiedOperation, I would think that an explicit interface declaration
would work around that issue, allowing the method to be public but
providing no means for external code to access it.

I've read Nicholas's reply to your posts, but I'm still not really clear
on what issue it is exactly you're having. If the above doesn't address
your concern, perhaps you can try to rephrase the question.

Pete
 
M

Moty Michaely

I'm not entirely clear about what you're asking about.

When I tried to compile the code you posted above, I got two errors, both
expected (at least to me):

OperationValidate was undefined, and
ProxiedOperation was not public

Since you provided no definition for OperationValidate, the error is not
surprising. This error is easily addressed by including an abstract
definition for the method in InvocableInternals. I don't see any problem
at all doing that.

Since interface members are required to be public, the second error is not
surprising either. This error is easily addressed by changing the
protection for ProxiedOperation so that it's public. The interface itself
is internal, so if you are concerned that InvocableInternals is public and
you don't want external code getting at the interface method
ProxiedOperation, I would think that an explicit interface declaration
would work around that issue, allowing the method to be public but
providing no means for external code to access it.

I've read Nicholas's reply to your posts, but I'm still not really clear
on what issue it is exactly you're having. If the above doesn't address
your concern, perhaps you can try to rephrase the question.

Pete

Hi,

I think the errors are reasonable and expected. I can't see any
problem with the errors. Why are they not expected?

Moty
 
J

Jon Skeet [C# MVP]

Ben Voigt said:
I've never understood this whole requirement about "type less visible than
...". Why can't I return an internal interface from a protected member
function, or vice versa?

Protected members are visible from methods outside the assembly. They
therefore couldn't understand what such a member meant if any of the
parameter types or the return type. I think it's reasonable to prevent
members from being visible if they couldn't actually be understood.
There are some perfectly valid combinations that
just can't be used currently. At most, the compiler should generate a
warning, definitely not an error.

No, I'm with the compiler on this front. However, it's a shame that
there isn't the *more* restrictive equivalent of "protected internal" -
i.e. "only visible to types which derive from this one *and* are in the
same assembly" - at which point it would be okay to return your
internal type.

However, that wouldn't solve your problem here - because interface
members are themselves implicitly public, so all the implementations
have to be public. It's very odd that the interface being internal
doesn't make all its members internal too.
 
B

Ben Voigt [C++ MVP]

Jon Skeet said:
Protected members are visible from methods outside the assembly. They
therefore couldn't understand what such a member meant if any of the
parameter types or the return type. I think it's reasonable to prevent
members from being visible if they couldn't actually be understood.


No, I'm with the compiler on this front. However, it's a shame that
there isn't the *more* restrictive equivalent of "protected internal" -
i.e. "only visible to types which derive from this one *and* are in the
same assembly" - at which point it would be okay to return your
internal type.

I'm often finding myself wanting an access level which is "members of the
enclosing type", but nothing like this is currently implemented.
 
B

Ben Voigt [C++ MVP]

Peter Duniho said:
I'm not entirely clear about what you're asking about.

When I tried to compile the code you posted above, I got two errors, both
expected (at least to me):

OperationValidate was undefined, and
ProxiedOperation was not public

Since you provided no definition for OperationValidate, the error is not
surprising. This error is easily addressed by including an abstract
definition for the method in InvocableInternals. I don't see any problem
at all doing that.

True, I hadn't done anything about OperationValidate.

But, the provided definition of ProxiedOperation, in my opinion, should be
accepted by the compiler. Why are only public (implicit interface
implementation) and private (explicit implementation) allowed? In this case
internal visibility is desired, and C# provides no way to get it without an
additional runtime cost.

What I also don't like, is that while interfaces can have any visibility,
abstract base classes must have at least the same visibility as the deriving
class. This is inconsistent and makes no sense (to me).
 
J

Jon Skeet [C# MVP]

Ben Voigt said:
I'm often finding myself wanting an access level which is "members of the
enclosing type", but nothing like this is currently implemented.

Do you mean "enclosing" in terms of nested classes? If so, private is
fine:

using System;

class Test
{
static string privateMember;

static void Main()
{
privateMember = "Private";
new Nested();
}

class Nested
{
internal Nested()
{
Console.WriteLine(privateMember);
}
}
}

If you actually mean base types, then it doesn't help you of course.
 
B

Ben Voigt [C++ MVP]

Jon Skeet said:
Do you mean "enclosing" in terms of nested classes? If so, private is
fine:

I mean in terms of nested classes, and I mean on a per-member of nested
class basis. e.g. the nested class itself is publicly visible, ala
list::iterator, but carries data only meaningful to the enclosing class.

You've used internal, but that really isn't a very close fit. Especially
because .NET seems to force everything even somewhat interrelated to be
thrown into a single assembly.
 
J

Jon Skeet [C# MVP]

But, the provided definition of ProxiedOperation, in my opinion, should be
accepted by the compiler. Why are only public (implicit interface
implementation) and private (explicit implementation) allowed? In this case
internal visibility is desired, and C# provides no way to get it without an
additional runtime cost.

One thing to note: explicit implementation isn't really private. It
doesn't fit in well with the normal public/internal/protected/private
etc taxonomy. It means "publicly available through an expression of the
interface type" - so it's effectively public if the interface is
public, because anyone could cast to the interface and then call the
method.
What I also don't like, is that while interfaces can have any visibility,
abstract base classes must have at least the same visibility as the deriving
class. This is inconsistent and makes no sense (to me).

It makes sense to me - if you derive a public type from an internal
type, how would I know (from a different assembly) what members you've
inherited? It's the same argument as the parameter/return type one,
basically - you shouldn't be able to see things which refer to things
you can't see.
 
J

Jon Skeet [C# MVP]

Ben Voigt said:
I mean in terms of nested classes, and I mean on a per-member of nested
class basis. e.g. the nested class itself is publicly visible, ala
list::iterator, but carries data only meaningful to the enclosing class.

You've used internal, but that really isn't a very close fit. Especially
because .NET seems to force everything even somewhat interrelated to be
thrown into a single assembly.

I've used an internal constructor (so that the enclosing class can see
it), but the class itself is implicitly private.
 
P

Peter Duniho

True, I hadn't done anything about OperationValidate.

Since your original specifically asked about that compiler error, I hope
you can see where at least some of my confusion originated. :)
But, the provided definition of ProxiedOperation, in my opinion, should
be
accepted by the compiler. Why are only public (implicit interface
implementation) and private (explicit implementation) allowed? In this
case
internal visibility is desired, and C# provides no way to get it without
an
additional runtime cost.

Can you elaborate on why having an explicit-but-internal interface doesn't
accomplish what you want? It seems to me that that _does_ give you
internal visibility, without any additional runtime cost.

I admit that it seems a little odd that the implementation of an interface
is required to be less protected than the interface itself. However, I
see that as simply one of the many simplifications that C# has chosen,
favoring consistent easily-defined behavior over flexibility.

It's not an unreasonable requirement that interfaces simply require all
implementations to be public, given that the interface itself can be
restricted and explicitly implemented. Doing so ensures that all
protection is decided at the interface level, rather than the
implementation level, which seems to me to be a good design for an
interface.
What I also don't like, is that while interfaces can have any visibility,
abstract base classes must have at least the same visibility as the
deriving
class. This is inconsistent and makes no sense (to me).

I suppose that's in the eye of the beholder. It makes a lot of sense to
me, because it seems odd to me that you might have a class that derives
from some class, but which does not expose that class's functionality. If
you want to incorporate functionality of a more-protected class in a given
class, then simply hide the more-protected class as a member, rather than
deriving from it.

At the very least, it seems to me that this rule doesn't restrict what you
can do. It just changes how you have to do it.

Pete
 
P

Peter Duniho

I admit that it seems a little odd that the implementation of an
interface is required to be less protected than the interface itself.

And of course, I meant "equally or less protected" here
 
B

Ben Voigt [C++ MVP]

Jon Skeet said:
I've used an internal constructor (so that the enclosing class can see
it), but the class itself is implicitly private.

"internal" just isn't the same as "enclosing class", it doesn't enforce
encapsulation anywhere near as well, in fact it breaks it because
Intellisense will show those "internal" members to all coders working on the
same assembly.

A private interface declared in the enclosing class works, with explicit
implementation, but then you have to qualify every call with the interface
name... still not very nice.
 
B

Ben Voigt [C++ MVP]

Jon Skeet said:
One thing to note: explicit implementation isn't really private. It
doesn't fit in well with the normal public/internal/protected/private
etc taxonomy. It means "publicly available through an expression of the
interface type" - so it's effectively public if the interface is
public, because anyone could cast to the interface and then call the
method.


It makes sense to me - if you derive a public type from an internal
type, how would I know (from a different assembly) what members you've
inherited? It's the same argument as the parameter/return type one,

How about "you don't, you see only members in my most derived types and in
public interfaces".
basically - you shouldn't be able to see things which refer to things
you can't see.

That principle totally eliminates inheritance as a means of reusing
implementation details. But I guess that's what the .NET architects wanted,
because they didn't provide non-public inheritance.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top