Is it possible to find out the type of an element at compile time without a class that implements IEnumerable <T>?

  • summary

    Ignore the case when the object cannot be represented as an array, is it possible to define an extension method (static), for example:

    public static ? ToArray<TSource>(this TSource source); 

    and returns an array of an object if it consists of any sequence of elements? And if so, what would it be ? ?

  • description

    I was thinking about the following declarations:

     public static TElement[] ToArray<TElement>(this IEnumerable<TElement> source); public static ? ToArray<TSource>(this IEnumerable source); 

    But I cannot assume that an unknown class should implement IEnumerable<T> or IEnumerable . I can’t even determine ? in the event that it is simply IEnumerable , which is beyond the scope of the general definition.

    And I also thought about the Array class:

     public static Array ToArray<TSource>(this TSource source); 

    But this means that the type of the element was unknown at compile time.

    So I'm wondering, is it possible to find out the type of an element at compile time without a class that implements IEnumerable<T> ?

0
source share
3 answers

Unfortunately, IEnumerator precedes generics, so it does not carry any type information with it; just IEnumerator GetEnumerator() makes String not so attractive as to try to insert this common implementation that you are trying to execute.

It has been a long time since I did C #, but I guess:

 public static TElement ToArray<TSource>(this IEnumerable<TElement> source); 

... should be fine:

 public static TElement[] ToArray<TElement>(this IEnumerable<TElement> source); 

It’s important to remember about extension methods β€” it's just syntactic sugar. They actually do not stick or enter into the types that they adorn. They are replaced at compile time with calls to the static method. Your mileage with extension methods will be different.

+1
source

What is your question? If you ask whether the type of elements in IEnumerable always known at compile time, then the answer is "no, it is not always known." Non-original IEnumerable does not apply any type of element. This is why you can define a foreach for any IEnumerable :

 IEnumerable items = GetItems(); foreach(SomeClass item in items) { ... } 

but this will InvalidCastException if one of the items elements cannot be added to SomeClass .

By the way, if you define a method like this:

 public static TElement[] MyToArray<TElement>(this IEnumerable<TElement> source); 

Then you can call it on string in .NET 2.0+, because string implements IEnumerable<string> in .NET 2.0 and 3.0 and IEnumerable<char> in 3.5+. In fact, the .ToArray() extension built into .NET can already be used on string if you don't define anything.

+1
source

It is not known at compile time and cannot be known.

For example, I could do:

 IEnumerable myCollection; string discriminator = Console.ReadLine(); if (discriminator == "string") { myCollection = new List<string>{"One", "Two", "Three", "Four"}; } else { myCollection = new int[]{1, 2, 3, 4}; } //what should be the type of the elements variable var elements = myCollection.ToArray(); 

Basically, depending on user input, myCollection will be either List<string> or int[] , two types that have almost nothing in common except enumerated ones.

So, in order for your ToArray method ToArray work, you can either introduce type safety and generics using IEnumerable<T> instead of IEnumerable , or use a collection of objects like object[] as the return type of your method.

+1
source

All Articles