1

I have a generic method that takes Enumerables of type T. In the event that T is also an Enumerable, I need to pass it to another function. However, since that function only takes Enumerables, and T is generic, it won't compile. I'm checking that T is Enumerable before I pass it - but clearly not in a way that solves this problem.

How can I do this?

(Obviously I could write another method that only takes IEnumerable< IEnumerable< T>>, and use that where relevant, but that seems inelegant.)

Example:

public static bool EnumerablesAreEqual<T>(IEnumerable<T> a, IEnumerable<T> b)
{
    foreach (T x in a)
    {
        if (x is Enumerable && !EnumerableContainsEnumerable(x, b))
            return false;
        if (!b.Contains(x))
            return false;
    }
    ...
}

I've looked at this post but I don't think it's quite the same issue.

Community
  • 1
  • 1
Ollyver
  • 359
  • 2
  • 14
  • 1
    What is the `Enumerable` in your `x is Enumerable`? Do you mean the interface `IEnumerable` or the interface `IEnumerable<>`, or is this some `class`? The class `System.Linq.Enumerable` it cannot be because that's a `static class`. – Jeppe Stig Nielsen Jul 14 '13 at 07:41
  • ...`a` and `b` are sets of the same type `T`, but `b` might contain sets that contain `a`? – sq33G Jul 14 '13 at 08:29
  • EnumerableContainsEnumerable is a method that checks whether the set of sets b contains the set x (I'll swap the order of the arguments so that's more obvious). – Ollyver Jul 15 '13 at 06:04

1 Answers1

5

The fact that you check the dynamic type of the variable doesn't change its static type, and that what it's used to check the call.

If you want to do that, you need a cast. You can use a checked cast to do it in one go:

Enumerable ex = x as Enumerable;
if (ex != null && !EnumerableContainsEnumerable(ex, b))
    return false;

The as operator checks whether the cast is possible: if it is it will return the casted object; if it is not, it will return null.

rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • Good solution, but depending on what `Enumerable` is there might not be an allowed conversion between `T` and `Enumerable`. Do you assume it's an interface? – Jeppe Stig Nielsen Jul 14 '13 at 07:43
  • But I "cannot declare a variable of static type System.Linq.Enumerable". Is it possible to declare ex as an IEnumerable of generic type? – Ollyver Jul 14 '13 at 07:54
  • @Ollyver: But if it is a static type, then `x` cannot be of that type! Maybe you are mixing several different types with the same name... – rodrigo Jul 14 '13 at 09:37
  • That is basically my question - how does your example work? Since if I use that exact code, I am declaring ex to be of static type, which it can't be; and if I instead declare ex to be an IEnumerable, I am once again using dynamic type checking. – Ollyver Jul 15 '13 at 06:23
  • @Ollyver: Now I don't understand the question... in your OP you say `x is Enumerable` and there `Enumerable` can't be a static type either. If your code compiles, so should mine. Remember that there is more than one type named `Enumerable` in .NET. – rodrigo Jul 15 '13 at 06:45
  • My original problem was that it wouldn't, in fact, compile - although that was because of passing a possibly-non-IEnumerable x into `EnumerableContainsEnumerable()`, rather than my `x is Enumerable` statement. I don't know much (anything) about Enumerable in .NET. My IDE claims that that Enumerable is a `System.Linq.Enumerable` - what are the other types that Enumerable could be? Could you point me to any references? (I can only find information on the System.Linq one, and I've not created my own class with that name.) – Ollyver Jul 15 '13 at 11:39