Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with inheritance and List<>

I have an abstract class called Grouping. I have a subclass called GroupingNNA.

public class GroupingNNA : Grouping {
  // blah blah blah
}

I have a List that contains items of type GroupingNNA, but is actually declared to contain items of type Grouping.

List<Grouping> lstGroupings = new List<Grouping>();
lstGroupings.Add(
  new GroupingNNA { fName = "Joe" });
lstGroupings.Add(
  new GroupingNNA { fName = "Jane" });

The Problem: The following LINQ query blows up on me because of the fact that lstGroupings is declared as List< Grouping> and fName is a property of GroupingNNA, not Grouping.

var results = from g in lstGroupings
              where r.fName == "Jane"
              select r;

Oh, and this is a compiler error, not a runtime error. Thanks in advance for any help on this one!

More Info: Here is the actual method that won't compile. The OfType() fixed the LINQ query, but the compiler doesn't like the fact that I'm trying to return the anonymous type as a List< Grouping>.

private List<Grouping> ApplyFilterSens(List<Grouping> lstGroupings, string fSens) {

  // This works now! Thanks @Lasse
  var filtered = from r in lstGroupings.OfType<GroupingNNA>()
                 where r.QASensitivity == fSens
                 select r;

  if (filtered != null) {
    **// Compiler doesn't like this now**
    return filtered.ToList<Grouping>();
  }
  else
    return new List<Grouping>();
  }
like image 455
Jagd Avatar asked May 13 '10 22:05

Jagd


People also ask

What is inheritance in oops with example?

OOP is all about real-world objects and inheritance is a way of representing real-world relationships. Here's an example – car, bus, bike – all of these come under a broader category called Vehicle. That means they've inherited the properties of class vehicles i.e all are used for transportation.

Why multiple inheritance in C# is not possible?

C# compiler is designed not to support multiple inheritence because it causes ambiguity of methods from different base class. This is Cause by diamond Shape problems of two classes If two classes B and C inherit from A, and class D inherits from both B and C.

What is inheritance explain in detail?

Inheritance is the process by which genetic information is passed on from parent to child. This is why members of the same family tend to have similar characteristics.

Can classes inherit each other?

Nope. Functionally,the representation of a derived classes includes a representation of each of each base class.


1 Answers

Try:

= from g in lstGroupings.OfType<GroupingNNA>()

this will skip any elements not of type GroupingNNA, and also make the compiler use GroupingNNA as the type for g.

In response to comment and edited question. No, the compiler will certainly not be happy about your changed collection, but you can fix that:

return new List<Grouping>(filtered.ToArray());

This relies on the fact that arrays in .NET are co/contra-variant, which allows the compiler to treat GroupingNNA[] as Grouping[] for the constructor.

Also, you don't need the if (filtered != null) check, you will get a collection in filtered, it might just not produce any elements, but filtered will always be non-null.

This means your code can be written as:

var filtered = from r in lstGroupings.OfType<GroupingNNA>()
               where r.QASensitivity == fSens
               select r;
return new List<Grouping>(filtered.ToArray());

or even just:

return new List<Grouping>((from r in lstGroupings.OfType<GroupingNNA>()
                           where r.QASensitivity == fSens
                           select r).ToArray());

or even shorter if you drop the linq syntax:

return new List<Grouping>((lstGroupings.OfType<GroupingNNA>()
    .Where(r => r.QASensitivity == fSens).ToArray());

Note that you can of course use OfType to go the other way as well:

return filtered.OfType<Grouping>().ToList();

there shouldn't be any big performance differences between the different ways here, if in doubt, measure it, but I would go with what you find easiest to read and understand.

like image 185
Lasse V. Karlsen Avatar answered Oct 14 '22 07:10

Lasse V. Karlsen