Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

64 views
Skip to first unread message

Ben Voigt [C++ MVP]

unread,
Jun 11, 2007, 10:32:40 AM6/11/07
to
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?


Nicholas Paldino [.NET/C# MVP]

unread,
Jun 11, 2007, 10:48:28 AM6/11/07
to
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?


--
- Nicholas Paldino [.NET/C# MVP]
- m...@spam.guard.caspershouse.com

"Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote in message
news:%236aN$VDrHH...@TK2MSFTNGP06.phx.gbl...

Ben Voigt [C++ MVP]

unread,
Jun 11, 2007, 10:51:11 AM6/11/07
to

"Nicholas Paldino [.NET/C# MVP]" <m...@spam.guard.caspershouse.com> wrote in
message news:uW%23gXcDr...@TK2MSFTNGP03.phx.gbl...

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

Nicholas Paldino [.NET/C# MVP]

unread,
Jun 11, 2007, 11:19:01 AM6/11/07
to
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]
- m...@spam.guard.caspershouse.com

"Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote in message

news:Oc4kUgDr...@TK2MSFTNGP06.phx.gbl...

Ben Voigt [C++ MVP]

unread,
Jun 11, 2007, 12:54:21 PM6/11/07
to

"Nicholas Paldino [.NET/C# MVP]" <m...@spam.guard.caspershouse.com> wrote in
message news:uOKVctDr...@TK2MSFTNGP02.phx.gbl...

> 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]

unread,
Jun 11, 2007, 1:31:53 PM6/11/07
to
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]
- m...@spam.guard.caspershouse.com

"Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote in message

news:entjJlEr...@TK2MSFTNGP05.phx.gbl...

Peter Duniho

unread,
Jun 11, 2007, 2:10:48 PM6/11/07
to
On Mon, 11 Jun 2007 07:51:11 -0700, Ben Voigt [C++ MVP]
<r...@nospam.nospam> wrote:

> 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

Moty Michaely

unread,
Jun 11, 2007, 2:38:30 PM6/11/07
to
On Jun 11, 9:10 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:

Hi,

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

Moty

Peter Duniho

unread,
Jun 11, 2007, 2:46:34 PM6/11/07
to
On Mon, 11 Jun 2007 11:38:30 -0700, Moty Michaely <Mot...@gmail.com>
wrote:

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

That's my question exactly. :)

Jon Skeet [C# MVP]

unread,
Jun 11, 2007, 3:07:17 PM6/11/07
to
Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:
> > 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?

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.

--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Ben Voigt [C++ MVP]

unread,
Jun 11, 2007, 3:25:04 PM6/11/07
to

"Jon Skeet [C# MVP]" <sk...@pobox.com> wrote in message
news:MPG.20d7adb...@msnews.microsoft.com...

> Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:
>> > 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?
>
> 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.

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

Ben Voigt [C++ MVP]

unread,
Jun 11, 2007, 3:29:55 PM6/11/07
to

"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote in message
news:op.ttrrg...@petes-computer.local...

> On Mon, 11 Jun 2007 07:51:11 -0700, Ben Voigt [C++ MVP]
> <r...@nospam.nospam> wrote:
>
>> 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.

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).

Jon Skeet [C# MVP]

unread,
Jun 11, 2007, 3:32:55 PM6/11/07
to
Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:
> > 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.

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.

Ben Voigt [C++ MVP]

unread,
Jun 11, 2007, 3:37:33 PM6/11/07
to

"Jon Skeet [C# MVP]" <sk...@pobox.com> wrote in message
news:MPG.20d7b3c...@msnews.microsoft.com...

> Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:
>> > 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.
>
> 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.

Jon Skeet [C# MVP]

unread,
Jun 11, 2007, 3:40:56 PM6/11/07
to
Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:

<snip>

> 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.

Jon Skeet [C# MVP]

unread,
Jun 11, 2007, 3:42:10 PM6/11/07
to
Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:
> > 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.

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

Peter Duniho

unread,
Jun 11, 2007, 3:53:27 PM6/11/07
to
On Mon, 11 Jun 2007 12:29:55 -0700, Ben Voigt [C++ MVP]
<r...@nospam.nospam> wrote:

> 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

Peter Duniho

unread,
Jun 11, 2007, 3:57:07 PM6/11/07
to
On Mon, 11 Jun 2007 12:53:27 -0700, Peter Duniho
<NpOeS...@nnowslpianmk.com> wrote:

> 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

Ben Voigt [C++ MVP]

unread,
Jun 12, 2007, 1:12:05 AM6/12/07
to

"Jon Skeet [C# MVP]" <sk...@pobox.com> wrote in message
news:MPG.20d7b5e...@msnews.microsoft.com...

> Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:
>> > 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.
>
> 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.

Ben Voigt [C++ MVP]

unread,
Jun 12, 2007, 1:15:40 AM6/12/07
to

"Jon Skeet [C# MVP]" <sk...@pobox.com> wrote in message
news:MPG.20d7b5a...@msnews.microsoft.com...

> Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:
>
> <snip>
>
>> 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,

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.

Ben Voigt [C++ MVP]

unread,
Jun 12, 2007, 1:19:48 AM6/12/07
to

"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote in message
news:op.ttrv7...@petes-computer.local...

> On Mon, 11 Jun 2007 12:29:55 -0700, Ben Voigt [C++ MVP]
> <r...@nospam.nospam> wrote:
>
>> 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.

No, it doesn't. You can't override such a method, which you could with a
real internal method. Then you need *another* virtual method, declared with
the correct visibility, with a private explicit implementation forwarder.
That requires an extra v-table slot, and an extra function call at runtime,
because it is called polymorphically, thus preventing the JIT from inlining.

Jon Skeet [C# MVP]

unread,
Jun 12, 2007, 2:27:13 AM6/12/07
to
Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:
> > 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.

Try using that class from outside the enclosing class and you won't be
able to - because the nested class itself isn't visible outside the
enclosing class.

> 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.

True.

Jon Skeet [C# MVP]

unread,
Jun 12, 2007, 2:35:15 AM6/12/07
to
Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:
> > 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".

Ick - I wouldn't like that at all.

> > 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.

I think you must be meaning something beyond the obvious, because the
idea that .NET stops you reusing implementation details via inheritance
is crazy in itself. Do you think that every class in the framework
reimplements all of its public members, rather than ever relying on the
base class's implementation? Do you do that when coding in .NET? Do you
always override *all* the virtual methods in *every* class? If not, you
*are* reusing implementation details via inheritance.

So, given that that can't be what you mean, what *do* you mean?

Ben Voigt [C++ MVP]

unread,
Jun 12, 2007, 2:43:05 AM6/12/07
to

"Jon Skeet [C# MVP]" <sk...@pobox.com> wrote in message
news:MPG.20d84ef...@msnews.microsoft.com...

> Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:
>> > 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".
>
> Ick - I wouldn't like that at all.
>
>> > 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.
>
> I think you must be meaning something beyond the obvious, because the
> idea that .NET stops you reusing implementation details via inheritance
> is crazy in itself. Do you think that every class in the framework
> reimplements all of its public members, rather than ever relying on the
> base class's implementation? Do you do that when coding in .NET? Do you
> always override *all* the virtual methods in *every* class? If not, you
> *are* reusing implementation details via inheritance.
>
> So, given that that can't be what you mean, what *do* you mean?

I mean that when you use inheritance, it's not an implementation detail.
It's a part of the public interface.

Ben Voigt [C++ MVP]

unread,
Jun 12, 2007, 2:41:46 AM6/12/07
to

"Jon Skeet [C# MVP]" <sk...@pobox.com> wrote in message
news:MPG.20d84d1...@msnews.microsoft.com...

> Ben Voigt [C++ MVP] <r...@nospam.nospam> wrote:
>> > 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.
>
> Try using that class from outside the enclosing class and you won't be
> able to - because the nested class itself isn't visible outside the
> enclosing class.

Guess you missed this in my earlier post: "the nested class itself is

Peter Duniho

unread,
Jun 12, 2007, 3:01:16 AM6/12/07
to
On Mon, 11 Jun 2007 22:19:48 -0700, Ben Voigt [C++ MVP]
<r...@nospam.nospam> wrote:

>> 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.
>
> No, it doesn't. You can't override such a method, which you could with
> a real internal method.

You seem to have shifted tracks here. I thought we were talking about the
question of restricting access to an interface implementation. When did
the question of whether the method can be overridden or not come up, and
in what way does the protection level of the method play a part?

Pete

Ben Voigt [C++ MVP]

unread,
Jun 12, 2007, 3:14:37 AM6/12/07
to

"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote in message
news:op.ttsq4...@petes-computer.local...

Only the entire thread, the title of which begins with "abstract class",
thereby strongly suggesting overrides. And starting out with the statement
that the implementation would be provided in a more derived class.

But in any case, I elaborated on why that method didn't work, as you
requested. Trust me, I'd already considered that before posting in the
first place.

In any case, once again, the question is:

How do you define an interface on an public abstract class, giving the
members less than public visibility, the implementation of which is provided
in the more derived class? Bonus for not requiring extra runtime
indirection, a call through the interface v-table should be enough.

Ben Voigt [C++ MVP]

unread,
Jun 12, 2007, 3:17:22 AM6/12/07
to
And sorry for my abrupt tone. I appreciate your help. It's just that
everyone seems to rewrite my question to fit the answer. Also it's way late
and I need to go sleep.

TTYL.

Peter Duniho

unread,
Jun 12, 2007, 3:59:54 AM6/12/07
to
On Tue, 12 Jun 2007 00:14:37 -0700, Ben Voigt [C++ MVP]
<r...@nospam.nospam> wrote:

> Only the entire thread, the title of which begins with "abstract class",
> thereby strongly suggesting overrides. And starting out with the
> statement that the implementation would be provided in a more derived
> class.

Sorry...I didn't realize that was still a question. Since you _can_
declare an interface method as "abstract", I'm not really clear on what
the problem is yet. Is it your assertion that even though you can declare
the interface method as abstract, you are not permitted to override it in
a derived class?

The only issue I ran into trying to do what it _appeared_ to me you were
trying to do was the protection level of the abstract method. Because the
interface requires everything to be public, you can't make the method
internal (or anything else for that matter). But you certainly can make
it abstract.

(But it turns out, you can't make it abstract and explicit at the same
time...my lightbulb finally goes on...see below)

> [...]


> In any case, once again, the question is:
>
> How do you define an interface on an public abstract class, giving the
> members less than public visibility, the implementation of which is
> provided in the more derived class? Bonus for not requiring extra
> runtime indirection, a call through the interface v-table should be
> enough.

I think I finally see what your objection is. My apologies if I should
have seen this earlier, but I have to say your initial post was not at all
clear about what you were asking about, at least not to me (see my
previous comments about the compiler error you quoted versus what you're
actually asking about).

Anyway, I see that I get the CS0106 error when I try to combine abstract
and explicit interface implementation. The help topic for this error
reads, in part: "The abstract keyword is not allowed on an explicit
interface declaration because an explicit interface implementation can
never be overridden."

For what it's worth, I made the assumption that you could combine abstract
and an explicit interface declaration to do what you want. You even
seemed to reinforce this idea when you wrote "Why are only public
(implicit interface
implementation) and private (explicit implementation) allowed?" I haven't
found a way to use an explicit implementation at all, except when the
implementation is actually defined in the class declaring it (that is,
it's not virtual or abstract). Your statement seems to me to say that it
_is_ allowed, which is what got me confused.

Not that that really matters...more a point of reference in case you're at
all curious why it is I didn't get what you were trying to say.

So, to sum up:

* You can override an implicit interface definition, including an
abstract one
* You cannot override an explicit interface definition, and
* You cannot make an interface implementation anything except public
(whether that implementation is abstract or concrete, implicit or
explicit, green or yellow, whatever)

I'll ignore the first one, since that's something you _can_ do. :)

I don't fully understand the second one, and the third one would only make
sense to me if you had the option of overriding explicit interface
definitions. Since you can't, I would agree that it would be useful to be
able to at least modify the access of an implemented method of an
interface to match the protection level of the interface itself.

I can see why if the interface were public, for example, the
implementation would have to be public, but I'm at a loss to explain why
when the interface is internal, the implementation still needs to be
public.

In other words, at this point I think I finally see what you're
complaining about, and I don't have an answer. Maybe someone else does
(I'm actually a bit surprised that no one else has jumped in yet with a
good explanation of what's going on here).

Pete

Jon Skeet [C# MVP]

unread,
Jun 12, 2007, 4:08:07 AM6/12/07
to
On Jun 12, 7:41 am, "Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote:
> > Try using that class from outside the enclosing class and you won't be
> > able to - because the nested class itself isn't visible outside the
> > enclosing class.
>
> Guess you missed this in my earlier post: "the nested class
> itself is publicly visible, ala list::iterator, but carries data only
> meaningful to the enclosing class."

If it only carries data meaningful to the enclosing class then why
have you made it public?

Jon

Jon Skeet [C# MVP]

unread,
Jun 12, 2007, 4:10:29 AM6/12/07
to
On Jun 12, 7:43 am, "Ben Voigt [C++ MVP]"

> > So, given that
> > that can't be what you mean, what *do* you mean?
>
> I mean that when you use inheritance, it's not an
> implementation detail. It's a part of the public interface.

Right - yes indeed. I hope you can see why I was confused!

Maybe it's just because I haven't done much C++, but it feels to me
like that's only natural. Is making it an implementation detail a
common concept outside C++?

I tend to prefer composition over inheritance anyway, which may be why
I've never felt it to be a problem.

Jon

Peter Duniho

unread,
Jun 12, 2007, 4:13:30 AM6/12/07
to
On Tue, 12 Jun 2007 01:08:07 -0700, Jon Skeet [C# MVP] <sk...@pobox.com>
wrote:

>> Guess you missed this in my earlier post: "the nested class
>> itself is publicly visible, ala list::iterator, but carries data only
>> meaningful to the enclosing class."
>
> If it only carries data meaningful to the enclosing class then why
> have you made it public?

I think he means _some_ of the data it carries is meaningful only to the
enclosing class. Presumably the class itself is public for a good reason.

I got the impression he went to bed (which is where I should be going
too), so you'll have to wait until tomorrow to find out if I'm right. :)

Pete

Peter Duniho

unread,
Jun 12, 2007, 4:20:14 AM6/12/07
to
On Tue, 12 Jun 2007 01:10:29 -0700, Jon Skeet [C# MVP] <sk...@pobox.com>
wrote:

> On Jun 12, 7:43 am, "Ben Voigt [C++ MVP]"

>> I mean that when you use inheritance, it's not an
>> implementation detail. It's a part of the public interface.
>
> Right - yes indeed. I hope you can see why I was confused!
>
> Maybe it's just because I haven't done much C++, but it feels to me
> like that's only natural. Is making it an implementation detail a
> common concept outside C++?

At the risk of taking this thread away from the topic that Ben actually
wanted to talk about...

I'm unclear on the statement that "when you use inheritance, it's not an

implementation detail. It's a part of the public interface".

The way I read that, it's saying that in C#, inheritance is specifically
about defining the public methods a class exposes.

But I have to say, that's not the extent to which I use inheritance at
all, even in C#. You can inherit protected members, just as you can in
C++, and they provide the same benefit: an _implementation_ that is
reusable by the derived class. For that matter, private members may be
part of the inherited implementation as well.

So I'm confused about why inheritance is _not_ an implementation detail.

Since you both seem to agree on the point, maybe one of you can explain
what you're talking about to me. :)

Thanks,
Pete

Jon Skeet [C# MVP]

unread,
Jun 12, 2007, 4:24:47 AM6/12/07
to
On Jun 12, 9:13 am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:

> > If it only carries data meaningful to the enclosing class then why
> > have you made it public?
>
> I think he means _some_ of the data it carries is meaningful only to the
> enclosing class. Presumably the class itself is public for a good reason.

In that case, one obvious way round it is to keep the class private,
but implement a public interface exposing the members he wants to be
public. That keeps creation etc tightly within the confines of the
enclosing class, while keeping public things public.

> I got the impression he went to bed (which is where I should be going
> too), so you'll have to wait until tomorrow to find out if I'm right. :)

True.

Jon

Ben Voigt [C++ MVP]

unread,
Jun 12, 2007, 9:31:24 AM6/12/07
to

"Jon Skeet [C# MVP]" <sk...@pobox.com> wrote in message
news:1181636687.7...@a26g2000pre.googlegroups.com...

> On Jun 12, 9:13 am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
> wrote:
>> > If it only carries data meaningful to the enclosing class then why
>> > have you made it public?
>>
>> I think he means _some_ of the data it carries is meaningful only to the
>> enclosing class. Presumably the class itself is public for a good
>> reason.
>
> In that case, one obvious way round it is to keep the class private,
> but implement a public interface exposing the members he wants to be
> public. That keeps creation etc tightly within the confines of the
> enclosing class, while keeping public things public.

But you also end up with a runtime dynamic cast every time the client passes
said object back to you.

Ben Voigt [C++ MVP]

unread,
Jun 12, 2007, 9:35:02 AM6/12/07
to

"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote in message
news:op.ttsur...@petes-computer.local...

Implementation details can be changed without any changes by the client.
Inheritance clearly breaks through encapsulation. You can't inherit from an
internal or otherwise visibility-restricted class, and therefore the client
can always use your class in ways that changes to inheritance would break.

Jon Skeet [C# MVP]

unread,
Jun 12, 2007, 9:46:57 AM6/12/07
to
On Jun 12, 2:31 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote:
> > In that case, one obvious way round it is to keep the class private,
> > but implement a public interface exposing the members he wants to be
> > public. That keeps creation etc tightly within the confines of the
> > enclosing class, while keeping public things public.
>
> But you also end up with a runtime dynamic cast every time the client passes
> said object back to you.

That's true - I hadn't considered the case where the object is passed
bi-directionally.

Jon

Peter Duniho

unread,
Jun 12, 2007, 1:00:30 PM6/12/07
to
On Tue, 12 Jun 2007 06:35:02 -0700, Ben Voigt [C++ MVP]
<r...@nospam.nospam> wrote:

> Implementation details can be changed without any changes by the client.
> Inheritance clearly breaks through encapsulation. You can't inherit
> from an
> internal or otherwise visibility-restricted class, and therefore the
> client
> can always use your class in ways that changes to inheritance would
> break.

Ahh...I see what you mean. I agree that's true. And in fact, I'll go one
further and point out that you can't even hide a public class as you
inherit it.

However, you can inherit from a class that has no public members, right?.
The interface issue aside (which I think I agree with you on), it is
possible to design a class that provides only functionality
(implementation details) but not a publicly accessible API (the methods
would be available only to the inheritor).

If you are dealing with a third-party class that you want to incorporate
without exposing to the client of your own class, I agree that's harder.
But as Jon says, there's always containment as an alternative to
inheritance.

I suppose C# could have included the access protection modifier in the
inheritance declaration portion of a class, as C++ does. There are in
fact a variety of things C++ allows that aren't possible or require
workarounds in C#. But I've just come to accept that these are design
decisions made with respect to simplifying the language. I can't say I
fully understand them, but I don't find them all that troublesome either.

What I do find troublesome is when I run across something in C# that _is_
very complicated and/or non-intuitive. It makes it a little harder to
just accept the other simplifications when C# does include things that can
easily cause even an experienced programmer to stumble.

Pete

Christof Nordiek

unread,
Jun 19, 2007, 5:33:19 AM6/19/07
to
"Ben Voigt [C++ MVP]" <r...@nospam.nospam> schrieb im Newsbeitrag
news:Oc4kUgDr...@TK2MSFTNGP06.phx.gbl...
>
> "Nicholas Paldino [.NET/C# MVP]" <m...@spam.guard.caspershouse.com> wrote
> in message news:uW%23gXcDr...@TK2MSFTNGP03.phx.gbl...
>
> 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; } }
> }
>

The Method ProxiedOperation in InvocableInternals is not accepted as
implementation of ProxiedOperation of IInvocable, because it's neither
public nor an explicit interface implementation.
You could try following

public abstract class InvocableInternals: IInvocableInternals
{
string IInvocableInternals.ProxiedOperation{get {return
ProxiedOperation;}}

internal abstract string ProxiedOperation {get;}

......
}

hth
Christof


Christof Nordiek

unread,
Jun 19, 2007, 5:48:47 AM6/19/07
to

"Jon Skeet [C# MVP]" <sk...@pobox.com> schrieb im Newsbeitrag
news:MPG.20d7adb...@msnews.microsoft.com...
>
> 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.
>
If the interface is public, all it's implemantations have to be public. But
if the interface is internal, the implementation of it's members remain
internal if they are implemented implicitly.

But yes, an extention of the interface mapping rules, such that members of
an internal interface can map on internal members may be usefull.

Christof


Jon Skeet [C# MVP]

unread,
Jun 19, 2007, 5:52:16 AM6/19/07
to
On Jun 19, 10:48 am, "Christof Nordiek" <c...@nospam.de> wrote:
> > 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.
>
> If the interface is public, all it's implemantations have to be public. But
> if the interface is internal, the implementation of it's members remain
> internal if they are implemented implicitly.

No they don't - they have to be declared public:

using System;

internal interface IFoo
{
void Bar();
}

class Test : IFoo
{
static void Main()
{
}

internal void Bar()
{
}
}

fails to compile with the error:
Test.cs(8,7): error CS0536: 'Test' does not implement interface member
'IFoo.Bar()'. 'Test.Bar()' is either static, not public, or
has the
wrong return type.

You *have* to make the method public in order to implement the
interface implicitly.

At least, that's as far as I can see - could you give an example of
what you mean?

Jon

Christof Nordiek

unread,
Jun 19, 2007, 6:42:17 AM6/19/07
to
"Christof Nordiek" <c...@nospam.de> schrieb im Newsbeitrag
news:%23BFXxal...@TK2MSFTNGP05.phx.gbl...

>
> "Jon Skeet [C# MVP]" <sk...@pobox.com> schrieb im Newsbeitrag
> news:MPG.20d7adb...@msnews.microsoft.com...
>>
>> 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.
>>
> If the interface is public, all it's implemantations have to be public.
> But if the interface is internal, the implementation of it's members
> remain internal if they are implemented implicitly.

Oops, I meant: the implementation of it's members remain internal if they
are implemented *explicitly*.

Christof


Christof Nordiek

unread,
Jun 19, 2007, 6:46:15 AM6/19/07
to
"Jon Skeet [C# MVP]" <sk...@pobox.com> schrieb im Newsbeitrag
news:1182246736....@g4g2000hsf.googlegroups.com...

> At least, that's as far as I can see - could you give an example of
> what you mean?

What I actually meant was 'explicitly' not 'implicitly'. I mixed them up
somehow.

Christof


Jon Skeet [C# MVP]

unread,
Jun 19, 2007, 9:10:50 AM6/19/07
to
On Jun 19, 11:42 am, "Christof Nordiek" <c...@nospam.de> wrote:
> > If the interface is public, all it's implemantations have to be public.
> > But if the interface is internal, the implementation of it's members
> > remain internal if they are implemented implicitly.
>
> Oops, I meant: the implementation of it's members remain internal if they
> are implemented *explicitly*.

In that they can't cast to the interface? Yes, that makes sense.

Jon

Ben Voigt [C++ MVP]

unread,
Jun 19, 2007, 11:42:17 AM6/19/07
to

"Christof Nordiek" <c...@nospam.de> wrote in message
news:OXlPx4ls...@TK2MSFTNGP03.phx.gbl...

Not quite. They are only callable from internal code, true, but unlike a
proper internal member:

(1) They can't be invoked on the class object, you have to cast to interface
first.
(2) They can't be abstract or virtual. You can implement the interface
again in a derived class, but then I think you can't refer to the base
implementation any longer.

>
> Christof
>


Ben Voigt [C++ MVP]

unread,
Jun 19, 2007, 11:44:15 AM6/19/07
to

"Christof Nordiek" <c...@nospam.de> wrote in message
news:egEvESls...@TK2MSFTNGP06.phx.gbl...

I know you can, but adds extra layers of indirection at runtime, entirely
needlessly.

>
> hth
> Christof
>


Christof Nordiek

unread,
Jun 19, 2007, 12:41:07 PM6/19/07
to
"Ben Voigt [C++ MVP]" <r...@nospam.nospam> schrieb
abput implicit implemented members of internal interfaces:

>
> Not quite. They are only callable from internal code, true, but unlike a
> proper internal member:
>
> (1) They can't be invoked on the class object, you have to cast to
> interface first.

This cast wouls only be a typecheck at compiletime.

> (2) They can't be abstract or virtual. You can implement the interface
> again in a derived class, but then I think you can't refer to the base
> implementation any longer.
>

You still can do all this. You can write internal members and then call this
from the implementations.

This surely is more code. That's why I said:

<quote>


But yes, an extention of the interface mapping rules, such that members of
an internal interface can map on internal members may be usefull.

</quote>

Christof


Christof Nordiek

unread,
Jun 19, 2007, 12:46:13 PM6/19/07
to
"Ben Voigt [C++ MVP]" <r...@nospam.nospam>
>> The Method ProxiedOperation in InvocableInternals is not accepted as
>> implementation of ProxiedOperation of IInvocable, because it's neither
>> public nor an explicit interface implementation.
>> You could try following
>>
>> public abstract class InvocableInternals: IInvocableInternals
>> {
>> string IInvocableInternals.ProxiedOperation{get {return
>> ProxiedOperation;}}
>>
>> internal abstract string ProxiedOperation {get;}
>>
>> ......
>> }
>
> I know you can, but adds extra layers of indirection at runtime, entirely
> needlessly.
>

Maybe, but only, because the implementors of C#/.NET didn't consider it
worth to optimize this away. I don't see why this should work different in
runtime.

More problem I see with the extra code which makes the code a bit less
readable and maintainable.

Christof


Ben Voigt [C++ MVP]

unread,
Jun 19, 2007, 12:52:59 PM6/19/07
to

"Christof Nordiek" <c...@nospam.de> wrote in message
news:u0v8KEp...@TK2MSFTNGP06.phx.gbl...

> "Ben Voigt [C++ MVP]" <r...@nospam.nospam>
>>> The Method ProxiedOperation in InvocableInternals is not accepted as
>>> implementation of ProxiedOperation of IInvocable, because it's neither
>>> public nor an explicit interface implementation.
>>> You could try following
>>>
>>> public abstract class InvocableInternals: IInvocableInternals
>>> {
>>> string IInvocableInternals.ProxiedOperation{get {return
>>> ProxiedOperation;}}
>>>
>>> internal abstract string ProxiedOperation {get;}
>>>
>>> ......
>>> }
>>
>> I know you can, but adds extra layers of indirection at runtime, entirely
>> needlessly.
>>
>
> Maybe, but only, because the implementors of C#/.NET didn't consider it
> worth to optimize this away. I don't see why this should work different in
> runtime.

I don't see how it can avoid being different at runtime. In order for the
JIT to remove the function call, it would have to inline the code, and it
doesn't have enough information for that.

Christof Nordiek

unread,
Jun 20, 2007, 7:27:28 AM6/20/07
to
"Ben Voigt [C++ MVP]" <r...@nospam.nospam> schrieb im Newsbeitrag
news:OOkMDKps...@TK2MSFTNGP03.phx.gbl...

>>>> You could try following
>>>>
>>>> public abstract class InvocableInternals: IInvocableInternals
>>>> {
>>>> string IInvocableInternals.ProxiedOperation{get {return
>>>> ProxiedOperation;}}
>>>>
>>>> internal abstract string ProxiedOperation {get;}
>>>>
>>>> ......
>>>> }
>>>
>>> I know you can, but adds extra layers of indirection at runtime,
>>> entirely needlessly.
>>>
>>
>> Maybe, but only, because the implementors of C#/.NET didn't consider it
>> worth to optimize this away. I don't see why this should work different
>> in runtime.
>
> I don't see how it can avoid being different at runtime. In order for the
> JIT to remove the function call, it would have to inline the code, and it
> doesn't have enough information for that.
>
Given that we compare explicit implementation of abstract class with calling
an abstract method in an explicit method:
In the first scenario the interface member has to be mapped to an method
wich itself is an entry in a v-table.
In the second scenario the runtime sees that the method is nothing more,
than a call of a virtual/abstract method and could transform this call in
absolute the same manner as in the first scenario.

Am I missing something?

Christof


Ben Voigt [C++ MVP]

unread,
Jun 20, 2007, 10:59:26 AM6/20/07
to

"Christof Nordiek" <c...@nospam.de> wrote in message
news:ujH2h2ys...@TK2MSFTNGP05.phx.gbl...

The abstract class explicit interface implementation will be called through
an interface, so it must be an entry in a v-table. The derived class
implementation is polymorphic (potentially many classes derived from the
abstract class), so it must be dispatched through the v-table as well.

If you could use "internal abstract ReturnType Method(arguments)" to
implement the interface, then the derived class method could be stored in
the interface v-table and invoked on the first dispatch. I don't see how
this is possible using the shim layer. You think that the JIT does reverse
inlining, where the interface v-table entry gets replaced by a derived
method that combines the base implementation with the (now known) inlined
derived instance? But that would break reflection, so I'm quite sure it
isn't being done.

public delegate void SimpleDelegate();

internal interface ISecret
{
void TellLocation();
}

public abstract class SecretBase : ISecret
{
abstract internal void TellLocation();
void ISecret.TellLocation() { TellLocation(); }
}

public class SecretHideout : SecretBase
{
internal void TellLocation() { ... }
}

public class SecretFortress : SecretBase
{
internal void TellLocation() { ... }
}

ISecret hideout = new SecretHideout();
ISecret fortress = new SecretFortress();

SimpleDelegate tell1 = hideout.TellLocation;
SimpleDelegate tell2 = fortress.TellLocation;

Assert.AreSame(tell1.Method, tell2.Method);


Now, can you suggest any way for the JIT to eliminate the second v-table
dispatch without breaking the assertion? With the alternate syntax, the
assertion would be expected to fail, but here there is only one
implementation of ISecret.TellLocation so it must succeed.


Christof Nordiek

unread,
Jun 25, 2007, 3:48:36 AM6/25/07
to
"Ben Voigt [C++ MVP]" <r...@nospam.nospam> schrieb im Newsbeitrag
news:%23lvD$u0sHH...@TK2MSFTNGP04.phx.gbl...

>
> public delegate void SimpleDelegate();
>
> internal interface ISecret
> {
> void TellLocation();
> }
>
> public abstract class SecretBase : ISecret
> {
> abstract internal void TellLocation();
> void ISecret.TellLocation() { TellLocation(); }
> }
>
> public class SecretHideout : SecretBase
> {
> internal void TellLocation() { ... }
> }
>
> public class SecretFortress : SecretBase
> {
> internal void TellLocation() { ... }
> }
>
> ISecret hideout = new SecretHideout();
> ISecret fortress = new SecretFortress();
>
> SimpleDelegate tell1 = hideout.TellLocation;
> SimpleDelegate tell2 = fortress.TellLocation;
>
> Assert.AreSame(tell1.Method, tell2.Method);
>
>
> Now, can you suggest any way for the JIT to eliminate the second v-table
> dispatch without breaking the assertion? With the alternate syntax, the
> assertion would be expected to fail, but here there is only one
> implementation of ISecret.TellLocation so it must succeed.
>

When generating the v-table entry for ISecret in class SecretHideout it
detects, that the implementation simply delegates the call to another
method. Then it lets the v-table entry point directly to that method.

If that really gives a performance boost in many cases, I'm sure they would
implement such optimization.

BTW: Do you have any evidence, that this isn't implemented in that way and
that this rises performance issues? Until now our discussion is only
theorie.

Christof


Ben Voigt [C++ MVP]

unread,
Jun 25, 2007, 9:13:27 AM6/25/07
to

"Christof Nordiek" <c...@nospam.de> wrote in message
news:eTPuhzvt...@TK2MSFTNGP04.phx.gbl...

Only that the optimization you describe is illegal because it would break
the example code I gave. Note that possibly Assert.AreSame is the wrong
test, really whether the MethodToken is the same is what matters.

>
> Christof
>


0 new messages