0

I am trying to test using 'as' keyword but get the null even though the variable I'm trying to test is a collection.

DoSomething(() => someMethodReturningCollection()); 
DoSomething(() => anotherMethodReturningAnObject());

public void DoSomething(Func<T> aFunc)
{
   var result = aFunc();
   var test = result as List<T>;

   if(test != null){
       DoTaskA();
       return;
   }

   //Here `result` is not a collection
   DoTaskB();
}

The test is always null. The typeof(T) shows as IEnumerable<T> otherwise.

I don't think this is a duplicate question I'm trying to test if a type is a collection or not by using the 'as' operator. The issue seems to be the List<T> v. List<string> or List<customer>. I can successfully test result as List<customer> but not result as List<T>. It seems the as operator expects an explicit type - not a T.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
Stack Undefined
  • 1,050
  • 1
  • 14
  • 23
  • Well, what kind of collection? What does result.GetType() say – Stilgar Apr 07 '21 at 22:33
  • _"The typeof(T) shows as IEnumerable otherwise"_ -- `IEnumerable` is completely different from `List`. If `as` returns `null`, it's simply the case that the object **is not the target type you asked for.** Simple as that. See duplicate for details about the distinctions between the two. – Peter Duniho Apr 07 '21 at 22:52
  • From other comments: "*The aFunc can either return a collection or a single object.*". What is `test` used for? – tymtam Apr 07 '21 at 22:55
  • @tymtam: the original question is a duplicate. It is not legitimate to go changing the actual question to something different, especially if you are not the actual author of the question in the first place. If you would like to answer a different question, go ahead and post that question and put your answer there. Don't edit existing questions to make them different. – Peter Duniho Apr 09 '21 at 00:53

1 Answers1

1

EDIT: Completly changed answer because of new facts.

You cannot treat T sometimes as T an sometimes as IEnumerbable.

Two methods

You could have two methods

void DoSomething<T>(Func<IEnumerable<T>> aFunc)
{
// Collection code
}

void DoSomething<T>(Func<T> aFunc)
{
// Single code 
}

One method, quite limited

This is the best I can do atm:

DoSomething<string>(() => new[] { "a", "b" });
DoSomething<string>(() => new List<string> { "a", "b" });
DoSomething<string>(() => "c"); 

void DoSomething<T>(Func<object> aFunc)
{
    var result = aFunc();

    if (result is IEnumerable<T>)
    {
        Console.WriteLine("collection!");
        return;
    }

    Console.WriteLine("single!");
}
collection!
collection!
single!

Always a IEnumerable

I'd make all you methods return IEnumerable and switch on the count of elements. Yes, this is different, but arguably better.

DoSomething(() => new[] { "a", "b" });
DoSomething(() => new List<string> { "a", "b" });
DoSomething(() => new[] { "c" });

void DoSomething<T>(Func<IEnumerable<T>> aFunc)
{
    var result = aFunc();

    if (!result.Any())
    {
        Console.WriteLine("empty!");
    } 
    else if (result.Count() > 1)
    {
        Console.WriteLine("collection!");
    } else 
    {
        Console.WriteLine("single!");
    }
}
tymtam
  • 31,798
  • 8
  • 86
  • 126
  • No, I'm not converting. I am testing to see if the `result` is a list or collection. The `result as List` is not null. It's when I use the `T` it always returns null. The typeof(T) at runtime is a IEnumerable so I'm not sure why the compiler use the actual type list `result as List` and test/convert. – Stack Undefined Apr 07 '21 at 22:45
  • BTW. Is it `IEnumerable` or `IEnumerable`? These are different types. – tymtam Apr 07 '21 at 22:46
  • IEnumerable. The aFunc can return either a collection or a single object. With `Func>`, I already know the the return type is a collection so no need to test for collection. – Stack Undefined Apr 07 '21 at 22:50
  • What's the signature of an example method you pass in? – tymtam Apr 07 '21 at 22:51
  • `DoSomething( () => someMethodReturningCollection() )` and `DoSomething( () => anotherMethodReturningSingleObject())` – Stack Undefined Apr 07 '21 at 22:55
  • Add these details to the question. You'll get better answers. – tymtam Apr 07 '21 at 23:00