473,756 Members | 5,656 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Generics, IEnumerable and Polymorphism

It looks to me that in using that in creating generic IEnumerables, you
lose polymorphic capabilities.

Consider this pseudo code:

abstract class BaseClass;

class DerivedClassSpe cialFunction1 : BaseClass
class DerivedClassSpe cialFunction2 : BaseClass

class Function1Implem entationA : DerivedClassSpe cialFunction1
class Function1Implem entationB : DerivedClassSpe cialFunction1
List<BaseClass> mylist = new List<BaseClass>

// assume the above list gets populated with a mix of the above classes

foreach (BaseClass item in mylist)
{
DerivedClassSpe cialFunction1 derivedItem = item as
DerivedClassSpe cialFunction1;

if (derivedItem != null)
{
derivedItem.Cal lSpecialFunctio n();
}
}

This allows me to iterate through a list of objects all subclassed from
the same absrtact class and then, for only specific types, call some
function. The function called is the correct function for the instance
type.

I then tried to create an IEnumerator method to try to clean this up a
bit (hoping to avoid testing for the right type everytime (and also
checking for null).

My iterator looked something like this:

public IEnumerator<Der ivedClassSpecia lFunction1>
GetSpecialFunct ion1ClassesOnly ()
{
foreach (BaseClass item in mylist)
{
if (item is DerivedClassSpe cialFunction1) yield return item;
}
}
So, later if I use this enumerator in a foreach call like this:

foreach (DerivedClassSp ecialFunction1 item in
GetSpecialFunct ionClassesOnly( ))
{
item.CallSpecia lFunction();
}

This does not work correctly. Instead of calling the
Function1Implem entationA version of CallSpecialFunc tion(), it always
uses the DerivedClassSpe cialFunction version.

Is there a way to do what I want and still use custom enumerators? I
want to selectively filter on type, but retain the polymorphic
abilities of subclasses from that type.

Thanks!

Mike

Dec 20 '05 #1
4 2056
Mike,
This does not work correctly. Instead of calling the
Function1Imple mentationA version of CallSpecialFunc tion(), it always
uses the DerivedClassSpe cialFunction version.


That's not what I'm seeing. Below is a cleaned up version of your code
that actually compiles. The output is

DerivedClassSpe cialFunction1
Function1Implem entationA
Function1Implem entationB

which is what I expect and seems perfectly polymorphic. If you get
something else please post your complete code. Here's mine:

using System;
using System.Collecti ons.Generic;

abstract class BaseClass
{
public virtual void CallSpecialFunc tion() {
Console.WriteLi ne("BaseClass") ; }
}

class DerivedClassSpe cialFunction1 : BaseClass
{
public override void CallSpecialFunc tion() {
Console.WriteLi ne("DerivedClas sSpecialFunctio n1"); }
}

class DerivedClassSpe cialFunction2 : BaseClass
{
public override void CallSpecialFunc tion() {
Console.WriteLi ne("DerivedClas sSpecialFunctio n2"); }
}

class Function1Implem entationA : DerivedClassSpe cialFunction1
{
public override void CallSpecialFunc tion() {
Console.WriteLi ne("Function1Im plementationA") ; }
}

class Function1Implem entationB : DerivedClassSpe cialFunction1
{
public override void CallSpecialFunc tion() {
Console.WriteLi ne("Function1Im plementationB") ; }
}

class Test
{
static List<BaseClass> mylist = new List<BaseClass> ();

public static IEnumerable<Der ivedClassSpecia lFunction1>
GetSpecialFunct ion1ClassesOnly ()
{
foreach (BaseClass item in mylist)
{
DerivedClassSpe cialFunction1 dcsf1 = item as
DerivedClassSpe cialFunction1;
if (dcsf1 != null) yield return dcsf1;
}
}

static void Main()
{

mylist.Add(new DerivedClassSpe cialFunction1() );
mylist.Add(new DerivedClassSpe cialFunction2() );
mylist.Add(new Function1Implem entationA());
mylist.Add(new Function1Implem entationB());

foreach (DerivedClassSp ecialFunction1 item in
GetSpecialFunct ion1ClassesOnly ())
{
item.CallSpecia lFunction();
}

}
}
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Dec 20 '05 #2
"Mike" <mi*********@mb na.com> a écrit dans le message de news:
11************* ********@g14g20 00...legro ups.com...

| So, later if I use this enumerator in a foreach call like this:
|
| foreach (DerivedClassSp ecialFunction1 item in
| GetSpecialFunct ionClassesOnly( ))
| {
| item.CallSpecia lFunction();
| }
|
| This does not work correctly. Instead of calling the
| Function1Implem entationA version of CallSpecialFunc tion(), it always
| uses the DerivedClassSpe cialFunction version.

I used the following code :

public abstract class BaseClass
{
}

public class DerivedClassSpe cialFunction1 : BaseClass
{
public virtual void CallSpecialFunc tion()
{
}
}

public class DerivedClassSpe cialFunction2 : BaseClass
{
}

public class Function1Implem entationA : DerivedClassSpe cialFunction1
{
public override void CallSpecialFunc tion()
{
}
}

public class Function1Implem entationB : DerivedClassSpe cialFunction1
{
public override void CallSpecialFunc tion()
{
}
}

private List<BaseClass> mylist = new List<BaseClass> ();

public IEnumerator<Der ivedClassSpecia lFunction1>
GetSpecialFunct ion1ClassesOnly ()
{
foreach (BaseClass item in mylist)
{
if (item is DerivedClassSpe cialFunction1)
yield return (DerivedClassSp ecialFunction1) item;
}
}
Then I use dthe following test code :

private void button1_Click(o bject sender, EventArgs args)
{
mylist.Add(new Function1Implem entationA());
mylist.Add(new DerivedClassSpe cialFunction2() );
mylist.Add(new Function1Implem entationB());
mylist.Add(new Function1Implem entationA());

IEnumerator<Der ivedClassSpecia lFunction1> iter =
GetSpecialFunct ion1ClassesOnly ();

while (iter.MoveNext( ))
iter.Current.Ca llSpecialFuncti on();

This then works perfectly calling the correct overriden method only on those
items that are derived from DerivedClassSpe cialFunction1.

If I change the test code to the following :

foreach (DerivedClassSp ecialFunction1 item in
GetSpecialFunct ion1ClassesOnly ())
{
item.CallSpecia lFunction();
}

.... then this doesn't even compile ! You can't use foreach on an
IEnumerator, only on an IEnumerable or an object that has a GetEnumerator()
method.

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Dec 20 '05 #3
"Joanna Carter [TeamB]" <jo****@not.for .spam> a écrit dans le message de
news: Ok************* ***@TK2MSFTNGP0 9.phx.gbl...

| If I change the test code to the following :
|
| foreach (DerivedClassSp ecialFunction1 item in
| GetSpecialFunct ion1ClassesOnly ())
| {
| item.CallSpecia lFunction();
| }
|
| ... then this doesn't even compile ! You can't use foreach on an
| IEnumerator, only on an IEnumerable or an object that has a
GetEnumerator()
| method.

My bad, I forgot to declare the GetSpecialFinct ion1ClassesOnly method as
static.

Like Mattias, Now I find this code works perfectly as expected.

Did you declare your CallSpecialFunc tion() as virtual and override where
necessary ??

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Dec 20 '05 #4
Thanks Mattias and Joanna,

I hate to say it, but turns out the problem was hidden elsewhere and
this so-called "loss of polymorphism" was the false symptom. I did not
trace through the code properly and mis-diagnosed the problem.

Turns out my IEnumerable code was all in perfect working order. This
is a relief as I had fooled myself into thinking a core OO concept had
been trashed by M$... but alas, it is just my ego that is trashed! ;-)

The system I am working on is complex (aren't they all, right?). There
is a method that looks for a context object that is transitory. If it
finds a current context, it will return an IEnumerable from this
context, otherwise it will build it's own empty one. Hard to explain
all the details on why, but the context was being queried at a time
when it could not have been set. This was my mistake. I assumed it
would be there at a time that it could not be. As a result, downstream
in the code, the symptom appeared to be a loss of polymorphism. Once I
traced through the code patiently and properly, it was plain as day for
me.

Thanks so much for taking the time to respond to my query. It was your
quick responses that got me to stop thinking it was a polymorphism
issue and to start looking for the real problem!

What a great community!

Thanks!

Mike

Dec 21 '05 #5

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

Similar topics

1
1327
by: Kamen Yotov | last post by:
Hello, I got my hands on the PDC preview version of whidbey and I think I managed to break the compiler/runtime with my first Generics/Iterators attempt. The reason I am posting it here is that I might be wrong, in which case, please correct me! The following program prints garbade instead the intended 5,6,1. I think it is printing the integer values of the pointers which represent some references... Any ideas?
13
2713
by: Sherif ElMetainy | last post by:
Hello I was just got VS 2005 preview, and was trying generics. I tried the following code int intArray = new int; IList<int> intList = (IList<int>) intArray; it didn't compile, also the following didn't compile
2
2876
by: Marc | last post by:
Given a class 'Invoice' with a property 'public IMyColl<IInvoiceLine> InvoiceLines' where 'IMyColl<T> : IList<T>' i would like to detect by reflection that 'InvoiceLines' is a 'System.Collection.Generic.IList'. When performing something like: 'if (typeof(IList<>).IsAssignableFrom(propertyInfo.Type))' where 'propertyInfo' obviously refers to the 'InvoiceLines', the result is always 'false' because indeed 'IList<object>' and...
2
2898
by: rajivpopat | last post by:
I've been reading a discussion thread at http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_frm/thread/119f8362a9f5ff52 regarding typecasting generic collections to classical collections and vice-a-versa I faced a similar problem and solved it slightly differently... The apporach i seems to work but i am sure someone has a better apporach for solving this problem. In my case i was using nHibernate which was...
19
1772
by: Fernando Cacciola | last post by:
I'm puzzled, Why and how _exactly_ is this: void Foo<T>(T v ) where T : Interface/Value/Class/class any better than this void Foo( Interface/Value/Class/object v )
3
1663
by: Wiktor Zychla [C# MVP] | last post by:
since generics allow us to implement several IEnumerable<T> interfaces on a single class, I think that "foreach" should somehow reflect that. suppose we have a enumerable class class C : IEnumerable, IEnumerable<int>, IEnumerable<string> { ... we are allowed to enumerate IEnumerable: foreach ( object item in o ) ...
6
4086
by: Mark Rae | last post by:
Hi, I'm in the process of updating an ASP.NET v1.1 web app to v2. The app uses ActiveDirectory a great deal, and I'm trying to use the new System.Collections.Generic namespace where possible, having been advised by several luminaries that that is a "good thing to do"... :-) However, I'm experiencing a problem with the IEnumerable interface. (N.B. I understand fully that I should be using the LDAP provider instead of the WinNT provider...
10
5032
by: =?Utf-8?B?S29ucmFkIFJ1ZG9scGg=?= | last post by:
Hello, I was wondering if C# 3.0 finally supported generic upcasting. Consider the following code which does work in C# 2: string xs = {"this", "is", "a", "test"}; object ys = xs; Now, analogously, I would expect the following to work as well:
4
1264
by: CSharper | last post by:
I have a sample as shown in the bottom on the mail. I am trying to see without changing anything in the way the As and Bs handled. I want to make it DRY using generics. I am really interested in the AddCollection method, I see the code repeatation just because the collection is different type. Any thoughts? Thanks, using System; using System.Collections.Generic;
0
9454
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10028
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9707
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8709
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6533
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5139
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3804
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3352
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2664
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.