0

Let's say I have a Child class that derives from a Parent class. How can I write the following function?

public bool IsListOfParent(object obj)
{
    // return true if obj implements IList<Parent> (including IList<Child>)
}

When I try return obj is IList<Parent> it returns false for an object of type List<Child>.

redcurry
  • 2,381
  • 2
  • 24
  • 38
  • 2
    You can't, because `IList` does not derive from `IList` as `IList` is invariant. You can check for `IReadOnlyList` though, but that might not be useful for you. (Invariant: since `IList` has both getters and setters, you can't assign a value of `IList` to it, because someone might try to assign a `Parent` value which is not a `Child` but a `Child2` object, so it must be invariant. Whereas `IReadOnlyList` is covariant because it only has getters.) – Charlieface Apr 26 '22 at 22:49
  • 2
    Does this answer your question? [Convert List to List](https://stackoverflow.com/questions/1817300/convert-listderivedclass-to-listbaseclass) in particular [the great Eric Lippert's answer](https://stackoverflow.com/a/1817341/14868997) – Charlieface Apr 26 '22 at 22:52
  • 1
    @Charlieface I don't see why that would be a duplicate... It is quite obvious why cast does not work, but the question (to me) is about categorizing unrelated types rather than casting one type to another. (Should be easy to answer too - check if type is particular generic interface, get type used to construct that type and check if it same/derived from a given type). – Alexei Levenkov Apr 26 '22 at 23:00
  • @AlexeiLevenkov Yes, the link is not exactly the answer. I don't want to change the type of anything. I simply want to test whether a value is a generic list of elements that derive from `Parent`. – redcurry Apr 26 '22 at 23:05
  • And yet you accepted the duplicate... Make sure you decide what exactly you wanted to achieve before asking new/reopening if that duplicate didn't really answer the question. – Alexei Levenkov Apr 26 '22 at 23:07
  • @AlexeiLevenkov Yeah, that was my mistake. The "duplicate" helped me answer my question, but it wasn't a direct answer. – redcurry Apr 26 '22 at 23:09
  • @AlexeiLevenkov But that has no informational value at all. It doesn't help you to know if `T` is derived from `Parent` because you cannot add a `Parent` object to the list (as it may actually be a `List` which will not accept it). Checking if it can cast to `IReadOnlyList` is actually useful information – Charlieface Apr 26 '22 at 23:10
  • 1
    @redcurry What exactly are you trying to do with the information from `IsListOfParent`? In other words: what are you doing that checking a cast to a covariant type such as `IReadOnlyList` does not work? – Charlieface Apr 26 '22 at 23:10
  • @Charlieface I totally agree that the particular information the question asks about is not exactly practical, I only wanted to point out that question looked different. – Alexei Levenkov Apr 26 '22 at 23:13
  • @Charlieface I suppose that checking a cast to `IReadOnlyList` could work since I'm not modifying the list. To clarify, the `object` parameter does not need to implement `IReadOnlyList`, correct? In my case, it's possible for the `object` to be an `ObservableCollection`, which doesn't appear to implement `IReadOnlyList`. – redcurry Apr 26 '22 at 23:43
  • 1
    No it doesn't have to, but then it will return false if you do `return obj is IReadOnlyList;` incidentally `ObservableCollection` inherits from `Collection` which does implement `IReadOnlyCollection` and `IReadOnlyList` so that would work – Charlieface Apr 27 '22 at 00:05
  • I see why I didn't see `IReadOnlyList`. I'm using .NET Framework 4.0 and `IReadOnlyList` was introduced with .NET Framework 4.5. – redcurry Apr 27 '22 at 14:21

0 Answers0