473,396 Members | 2,003 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Implementing an interface with qualified templates

I want to do something like this:

public class Animal;

public interface IZoo
{
List<Animal> Animals { get; }
void Feed(Animal a);
}

public Aquarium<FISH> : IZoo where FISH : Animal
{
public List<FISH> Animals { get ...;}
public void Feed(FISH a) {...}
}

It seems like this should be possible, because FISH are guaranteed to be
Animals. I can dodge the generic collection problem by substituting an
ArrayList for the List<>, but I don't see why I have to. And then there's
the problem of the function argument.

Is there any way to implement a (non-templated) interface with a qualified
template, like what I'm suggesting here?
Jun 28 '06 #1
6 1760
Dave Booker wrote:
I want to do something like this:

public class Animal;

public interface IZoo
{
List<Animal> Animals { get; }
void Feed(Animal a);
}

public Aquarium<FISH> : IZoo where FISH : Animal
{
public List<FISH> Animals { get ...;}
public void Feed(FISH a) {...}
}

It seems like this should be possible, because FISH are guaranteed to be
Animals. I can dodge the generic collection problem by substituting an
ArrayList for the List<>, but I don't see why I have to. And then there's
the problem of the function argument.

Is there any way to implement a (non-templated) interface with a qualified
template, like what I'm suggesting here?


Hi Dave,

The problem is that List<FISH> is not List<Animal>. Due to the nature of
generics, they're totally different types, regardless of whether or not
FISH is in your where clause. Basically, A List<FISH> is not a subset of
List<Animal>, even if FISH is a subset of Animal.

Not only that, when you implement an interface it must be implemented
exactly, you can't use a subclass in place of what the interface is
expecting, i.e. 'void Feed ( FISH a )' instead of 'void Feed ( Animal a )'.

So, what you could do is implement the interface explicitly and then expose
public accessors to the implementation. I've condensed FISH to F for
brevity.

///
public class Aquarium<F> : IZoo where F : Animal
{
// Explicit implementation
List<Animal> IZoo.Animals { get { ... } }
void IZoo.Feed ( Animal a ) { ... }

// Accessible implementation
public List<F> Animals
{
get
{
// Difficult; because you'll need to convert
// the List<Animal> to List<F>.
}
}

public void Feed ( F a )
{
// Easy; because of the where clause 'a' will be a
// subclass of Animal.
( (IZoo) this ).Feed( a );
}
}
///

--
Hope this helps,
Tom Spink
Jun 29 '06 #2
Dave,

Why not just declare the interface as generic?

public class Animal
{}

public class Fish : Animal
{}

public interface IZoo<T> where T : Animal
{
List<T> Animals { get; }
void Feed(T a);
}

public Aquarium : IZoo<Fish>
{

}

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Dave Booker" <db******@newsgroup.nospam> wrote in message
news:0C**********************************@microsof t.com...
I want to do something like this:

public class Animal;

public interface IZoo
{
List<Animal> Animals { get; }
void Feed(Animal a);
}

public Aquarium<FISH> : IZoo where FISH : Animal
{
public List<FISH> Animals { get ...;}
public void Feed(FISH a) {...}
}

It seems like this should be possible, because FISH are guaranteed to be
Animals. I can dodge the generic collection problem by substituting an
ArrayList for the List<>, but I don't see why I have to. And then there's
the problem of the function argument.

Is there any way to implement a (non-templated) interface with a qualified
template, like what I'm suggesting here?

Jun 29 '06 #3
Hi Dave,

Thank you for posting.

I agree with what Tom has said about this issue. List<FISH> is not a subset
of the List<Animal> even if FISH is a subset of Animal.

A class that implements an interface must explicitly implement members of
that interface. It is optional for you to implicitly implement members of
the interface. An explicitly implemented member cannot be accessed through
a class instance, but only through an instance of the interface. On the
contrary, an implicitly implemented member cannot be accessed through an
instance of the interface, but only through a class instance.

Here is a sample of interface implementation for you.

public class Aquarium<T> : IZoo where T :Animal
{
private List<T> _animals;

public Aquarium()
{
this._animals = new List<T>();
}

#region explicitly implementation

List<Animal> IZoo.Animals
{
get
{
// you must create a new intance of List<Animal> and return it
List<Animal> animallist = new List<Animal>();
for (int i = 0; i < _animals.Count; i++)
{
animallist.Add(_animals[i]);
}
return animallist;
}
}

void IZoo.Feed(Animal a)
{
MessageBox.Show("explicitly feed");
}

#endregion
#region implicitly implementation

public List<T> Animals
{
get { return _animals; }
}

public void Feed(T a)
{
MessageBox.Show("implicitly feed.");
}

#endregion
}

Hope this helps.
If you have anything unclear, please don't hesitate to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support

================================================== ==
When responding to posts,please "Reply to Group" via
your newsreader so that others may learn and benefit
from your issue.
================================================== ==

Jun 29 '06 #4
Thank you all, this does answer my question as to what is possible with C# in
..NET 2.0.

If I may digress into more theoretical questions: Isn't is possible, in
theory, for the compiler to automatically upcast template members? I.e., I
understand, for example, that List<Animal> is a different type from
List<Fish>, but if Fish : Animal then the compiler should be able to see that
List<Fish> : List<Animal>, so anyone wanting a List<Animal> will be happy
taking a List<Fish>.

Since the compiler is playing dumb in this regard I end up either having to
do all sorts of explicit implementations (as you suggested), or else having
to keep things very general and do all sorts of downcasting, which means that
errors that could be detected at compile time end up not being detected until
runtime.

For example, I have delegates and eventhandlers, some of which can work on
any Animal, and some of which require specific animals:

public delegate void Feeding<T>(T a);

public interface IZoo
{
List<Animal> Animals { get; }
void Feed(Animal a);
event Feeding<Animal> Cleanup;
}

.... and of course, for my Aquarium to work I now have to add a second event
like this:

public class Aquarium<FISH> : IZoo where FISH : Animal
{
private List<FISH> _animals;
public event Feeding<Animal> Cleanup;
public event Feeding<FISH> CleanupGravel;

Is it asking too much for it to see that Feeding<FISH> satisfies
Feeding<Animal>?
Jun 29 '06 #5
Dave Booker <db******@newsgroup.nospam> wrote:
Thank you all, this does answer my question as to what is possible with C# in
.NET 2.0.

If I may digress into more theoretical questions: Isn't is possible, in
theory, for the compiler to automatically upcast template members? I.e., I
understand, for example, that List<Animal> is a different type from
List<Fish>, but if Fish : Animal then the compiler should be able to see that
List<Fish> : List<Animal>, so anyone wanting a List<Animal> will be happy
taking a List<Fish>.


No - because someone could add a Dog to a List<Animal>, but shouldn't
be able to add a Dog to a List<Fish>.

Basically, this is a covariance/contravariance issue - and C# doesn't
support either at the moment (and nor do the standard libraries) even
though the CLR is up to the job.

--
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
Jun 29 '06 #6
Hi Dave,

Thank you for your response.
Isn't it possible, in theory, for the compiler to automatically upcast template members?

From the view of the List<T> type itself, the List<Fish> type has no
relation to the List<Animal> type. The List<Fish> type is not inherited
from the List<Animal> type. So in my opinion, it is impossible for the
compiler to automatically cast List<Fish> to List<Animal>.
or else having to keep things very general and do all sorts of downcasting, which means that errors that could be detected at compile
time end up not being detected until runtime.

If you want to add or modify the object in the List<T> in the Aquarium<T>
class, to ensure compiler could detected errors(e.g you add an instance of
Animal to the List<T>, which should be an instance of Fish), I recommend
you to access the List<T> object through an instance of Anqurium instead
of an instance of IZoo.
Is it asking too much for it to see that Feeding<FISH> satisfies

Feeding<Animal>?

If some of the delegates and event handlers can work on any Animal, while
others require specific animals, you should add those events that applies
to any Animal in the interface IZoo and add those events that applies to
specific animal, e.g Fish, in the class Aquarium<T>, because they are
different kinds of events.

Hope this is helps.
If you have anything unclear, please don't hesitate to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

================================================== ==
When responding to posts,please "Reply to Group" via
your newsreader so that others may learn and benefit
from your issue.
================================================== ==

Jun 30 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Martyn Lawson | last post by:
Hi, I am currently working as an Analyst on a .NET Web Project using ASP.NET and C#.NET. I have a couple of, at least what should be, quick questions: 1. My understanding of UML says that...
4
by: Chris Schadl | last post by:
Hi, I've written a simple sorted linked list class that I'm trying to implement an iterator for. I'm trying to make the interface to the iterator simmilar to the STL's iterator interface, so...
4
by: Frank J. Reashore | last post by:
Hello Everyone, I am implementing a simple interface in C# using Visual Studio .net and was quite surprised to discover that the C# compiler does NOT complain if a method on the interface is not...
5
by: Jeff Louie | last post by:
Can anyone explain why a interface method implementation using the fully qualified name cannot be public or protected? Sample below: public interface IDrawable { void DrawYourself(); } public...
6
by: Kevin Yu | last post by:
hi all is there a way to pass an interface as input parameter for a web method? since interface is not serializable, does that mean it's impossible to do that? Kevin
2
by: Kevin Frey | last post by:
Consider this simple example: interface IReader { bool Read( ); }; class MyReader : IReader { bool Read( ); // or should it be bool IReader.Read( ) ?
9
by: Spam Catcher | last post by:
Hi all, Can anyone recommend any books for User Interface Engineer for Windows Forms application? At the company I work at, we've gone GUI component happy. Basically GUI tools (i.e....
13
by: interec | last post by:
I have some code in Java that I need to translate into C++. My Java code defines a class hierarchy as follows: // interface IA public interface IA { public abstract void doA(); } //...
6
by: Raj Wall | last post by:
Hi, I am trying to implement the IEqualityComparer interface for a struct so I can use it as the Key for a Dictionary. My struct declaration has: public struct Ring : IEqualityComparer {...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.