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>();
}
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.
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.
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.
Nope. Functionally,the representation of a derived classes includes a representation of each of each base class.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With