a case for multiple inheritance

  • Thread starter Thread starter John
  • Start date Start date
J

John

Hi All,
Although C# has Generics, it still does not support the generic
programming paradigm. Multiple inheritance is required to support real
generic programming. Here is a simple design pattern to illustrate this.

Problem:
I need to expose two lists of objects from a high-level class. I would
like to expose these lists as read-only, but require write access
internally.

Solution:
1) Create a generic ProtectedList<T> class which inherits from List<T>
and overrides the write functions (using the new modifier) to change the
access level from public to protected.
2) Inherit both specialized List<T> by the high-level class

Discussion:
While this usage of inheritance does not conform to the "is-a" relation
imposed by the OOP paradigm, it is a simple and easy way to reuse code
in a generic way.

Thanks for any thoughts, and good solutions to this problem in the
existing C# paradigm.
 
John said:
Hi All,
Although C# has Generics, it still does not support the generic
programming paradigm. Multiple inheritance is required to support real
generic programming. Here is a simple design pattern to illustrate this.

Problem:
I need to expose two lists of objects from a high-level class. I would
like to expose these lists as read-only, but require write access
internally.

Solution:
1) Create a generic ProtectedList<T> class which inherits from List<T>
and overrides the write functions (using the new modifier) to change the
access level from public to protected.
2) Inherit both specialized List<T> by the high-level class

Discussion:
While this usage of inheritance does not conform to the "is-a" relation
imposed by the OOP paradigm, it is a simple and easy way to reuse code
in a generic way.

Thanks for any thoughts, and good solutions to this problem in the
existing C# paradigm.

Hi John,
1) Create a generic ProtectedList<T> class which inherits from List<T>
and overrides the write functions (using the new modifier) to change the
access level from public to protected.

Mhm. FYI The 'new' modifier will define a method as hiding a derived one,
however, take a look at this:

public class A
{
public void Foo ()
{
Console.WriteLine("Foo in A");
}
}

public class B : A
{
private new void Foo ()
{
Console.WriteLine("Foo in B");
}
}

public class E
{
public static void Main ()
{
B b = new B();
b.Foo();
}
}

The output of this will be "Foo in A", because the accessible method from A
is called. If you change the scope of 'Foo' in B to public, the output
will be "Foo in B" as is expected. And, even more interestingly, if you
cast b to A and call 'Foo':

((A)b).Foo();

You'll get A's implementation of 'Foo'. So, as you can see, using the new
keyword will not give you the desired effect here.
2) Inherit both specialized List<T> by the high-level class
Can you explain this a bit more? I'm not sure why you need multiple
inheritance here. If you want to expose two read-only lists from your
high-level class, you can expose them as properties that return an array of
your list's type, then call the ToArray method of the associated list.
 
Tom said:
Mhm. FYI The 'new' modifier will define a method as hiding a derived one,

Sorry, I didn't complete the description, the 'new protected' modified
functions would delegate to the base implementation. I would assume that
the compiler would optimize it so that the double function call would be
reduced to a single function call resulting in no performance hit.
however, take a look at this:

public class A
{
public void Foo ()
{
Console.WriteLine("Foo in A");
}
}

public class B : A
{
private new void Foo ()
{
Console.WriteLine("Foo in B");
}
}

public class E
{
public static void Main ()
{
B b = new B();
b.Foo();
}
}

The output of this will be "Foo in A", because the accessible method from A
is called. If you change the scope of 'Foo' in B to public, the output
will be "Foo in B" as is expected. And, even more interestingly, if you
cast b to A and call 'Foo':

((A)b).Foo();

You'll get A's implementation of 'Foo'. So, as you can see, using the new
keyword will not give you the desired effect here.

The automatic fallback to the public base implementation, after
specifically overriding it, is very disturbing to me. The cast not much
of a surprise, assuming you are allowed to perform that cast, I would
expect that behavior.
Can you explain this a bit more? I'm not sure why you need multiple
inheritance here. If you want to expose two read-only lists from your
high-level class, you can expose them as properties that return an array of
your list's type, then call the ToArray method of the associated list.

Thanks for the advice, as you can tell, I'm new to C# and I'm looking
for these kinds of tips. The idea of multiple inheritance is to not
require this kind of massaging and wrapping for every 'ProtectedList'
you want to expose. I want to expose all the useful read-only List
interface like Exists, Equals, access methods, including custom sort
iterators with Predicate, etc., in as simple a way to program as
possible. Aggregating, and exposing wrappers is not, in my mind, an
efficient way to do this.
 
John said:
Sorry, I didn't complete the description, the 'new protected' modified
functions would delegate to the base implementation. I would assume that
the compiler would optimize it so that the double function call would be
reduced to a single function call resulting in no performance hit.


The automatic fallback to the public base implementation, after
specifically overriding it, is very disturbing to me. The cast not much
of a surprise, assuming you are allowed to perform that cast, I would
expect that behavior.


Thanks for the advice, as you can tell, I'm new to C# and I'm looking
for these kinds of tips. The idea of multiple inheritance is to not
require this kind of massaging and wrapping for every 'ProtectedList'
you want to expose. I want to expose all the useful read-only List
interface like Exists, Equals, access methods, including custom sort
iterators with Predicate, etc., in as simple a way to program as
possible. Aggregating, and exposing wrappers is not, in my mind, an
efficient way to do this.

Hi John,
Sorry, I didn't complete the description, the 'new protected' modified
functions would delegate to the base implementation. I would assume that
the compiler would optimize it so that the double function call would be
reduced to a single function call resulting in no performance hit.

Not really. Remember, C# gets compiled to a form of intermediate language,
with all OO constructs preserved, i.e. namespaces, classes, methods,
interfaces and etc. This means that if method A1 (in a subclass) overrides
method A2 (in a superclass), and A1 simply calls the superclass'
implementation, the call stack will still go from A1 to A2, there'll be no
optimisation like in a native language (such as C).
The automatic fallback to the public base implementation, after
specifically overriding it, is very disturbing to me. The cast not much
of a surprise, assuming you are allowed to perform that cast, I would
expect that behavior.

Now, this is an example of compiler inference. In truth, I didn't test this
on Microsoft's compiler (I used gmcs), but this is an example of where the
compiler can infer what you're trying to do. The compiler can infer that
if you're requesting a method call to 'Foo', and 'Foo' exists as private in
the class you are referencing, however a superclass has a public
implementation, then the compiler will route the call to the superclass'
implementation, and will indeed perform the cast that I described above to
force an invocation of a specific implementation of the method.

And, in my example, of course the cast is valid since B subclasses A.
Thanks for the advice, as you can tell, I'm new to C# and I'm looking
for these kinds of tips. The idea of multiple inheritance is to not
require this kind of massaging and wrapping for every 'ProtectedList'
you want to expose. I want to expose all the useful read-only List
interface like Exists, Equals, access methods, including custom sort
iterators with Predicate, etc., in as simple a way to program as
possible. Aggregating, and exposing wrappers is not, in my mind, an
efficient way to do this.

No problem. However, I'm still trying to understand where multiple
inheritance relates to your problem. Can you provide an example of how
you'd use multiple inheritance?

Thanks,
 
Tom said:
Can you explain this a bit more?

I just realized, that inheritance doesn't work, gawd, I should have
written out the code before posting. Sorry, I guess I was looking for a
silver bullet. I would assume that exposing a List as read-only outside
it's container class should be a good candidate for generics but at the
moment I can't find a good answer.
 
John said:
Sorry, I didn't complete the description, the 'new protected' modified
functions would delegate to the base implementation. I would assume that
the compiler would optimize it so that the double function call would be
reduced to a single function call resulting in no performance hit.

That is not the point here. If ProtectedList<T> derives from List<T> than
all members of List<T> would be callable on instances of ProtectedList<T>.
Hiding doesn't help here, it would only demand the caller to cast to List<T>
before calling the hidden member. Only writing inconvinience. No way to
prevent something.

Christof
 
John said:
Hi All,
Although C# has Generics, it still does not support the generic
programming paradigm. Multiple inheritance is required to support real
generic programming. Here is a simple design pattern to illustrate this.

Problem:
I need to expose two lists of objects from a high-level class. I would
like to expose these lists as read-only, but require write access
internally.

What ever your problem has to do with multiple inheritance it doesn't touch
Generics. The problem would remain the same if you used TList and
ProtectedTList instead of List said:
Solution:
1) Create a generic ProtectedList<T> class which inherits from List<T> and
overrides the write functions (using the new modifier) to change the
access level from public to protected.

You can't prevent access to inherited members. Even when hidden, it is still
accessible.
2) Inherit both specialized List<T> by the high-level class

I absolutly don't understand what this means. What are the two specialized
List<T>. I can only see List<T> and ProtectedList<T>. Since ProtectedList<T>
inherits from List<T> a class inheriting from ProtectedList<T> would also
inherit from List<T>, so it inherirts from both. Where MI comes into play.

Christof
 
John said:
Hi All,
Although C# has Generics, it still does not support the generic
programming paradigm. Multiple inheritance is required to support real
generic programming. Here is a simple design pattern to illustrate this.

Problem:
I need to expose two lists of objects from a high-level class. I would
like to expose these lists as read-only, but require write access
internally.

Solution:
1) Create a generic ProtectedList<T> class which inherits from List<T>
and overrides the write functions (using the new modifier) to change the
access level from public to protected.
2) Inherit both specialized List<T> by the high-level class

Discussion:
While this usage of inheritance does not conform to the "is-a" relation
imposed by the OOP paradigm, it is a simple and easy way to reuse code
in a generic way.

Thanks for any thoughts, and good solutions to this problem in the
existing C# paradigm.

You can simply write a Wrapper which manages the list internally, but
providing just getters for the elements to the outside.
 
Tom Spink said:
Hi John,

Not really. Remember, C# gets compiled to a form of intermediate
language,
with all OO constructs preserved, i.e. namespaces, classes, methods,
interfaces and etc. This means that if method A1 (in a subclass)
overrides
method A2 (in a superclass), and A1 simply calls the superclass'
implementation, the call stack will still go from A1 to A2, there'll be no
optimisation like in a native language (such as C).

The JIT is perfectly capable of inlining the function call mentioned.
 
Ben said:
The JIT is perfectly capable of inlining the function call mentioned.

Hi Ben,
The JIT is perfectly capable of inlining the function call mentioned.

I guess so... perhaps my wording wasn't the best, as I meant this sort of
optimisation won't happen at the IL compilation stage. It will be a
runtime optimisation.
 
Hi All,
Although C# has Generics, it still does not support the generic
programming paradigm. Multiple inheritance is required to support real
generic programming. Here is a simple design pattern to illustrate this.

Problem:
I need to expose two lists of objects from a high-level class. I would
like to expose these lists as read-only, but require write access
internally.

Hi John!
An easy way to solve the problem is using the
System.Collections.ObjectModel.ReadOnlyCollection class,
which wraps a collection. All modifying methods throw a
NotSupportedException.

Philip
 
The JIT is perfectly capable of inlining the function call mentioned.
I guess so... perhaps my wording wasn't the best, as I meant this sort of
optimisation won't happen at the IL compilation stage. It will be a
runtime optimisation.

Well, you replied to a comment about the optimizing compiler, and for .NET,
that *is* the JIT. So while you're right that the C# compiler won't
optimize it, it's because there is no optimizing C# compiler. The only
option you have is to stuff the program with tons of extra space for the
debugger to use, or not. All real optimization is done in the JIT (or by
ngen, if you take that route).
 
Back
Top