1

Is there some way to get a java List<?> in C#?

I need to get a IEnumerable<T>, where T can be either a class (string), or a struct (int, double...).

public interface I
{
    IEnumerable<object> Enumers { get; }
}

public class A<T> : I
{
    IEnumerable<T> ts;

    public IEnumerable<object> Enumers
    {
        get { return (IEnumerable<object>)this.ts; }
    }
}

public class Test
{
    public static void Main()
    {
        A<double> a = new A<double>();
        var x = a.Enumers;  //It crashes here.
    }
}

It crashes at runtime, since it's not possible to cast from IEnumerable<T> to IEnumerable<object>.

Any ideas?

11
  • 2
    What are you trying to get this code to do? There may be a better c# alternative altogether. Commented Jun 8, 2016 at 13:25
  • Classes and structs are very different beasts (reference and value semantics). Mixing them in the same collection sounds problematic. Commented Jun 8, 2016 at 13:25
  • you would need to add an explicit cast for your var x = a.Enumers; line... could use Linq Commented Jun 8, 2016 at 13:25
  • 2
    get { return this.ts.Cast<object>(); } this would give you back the IEnumerable<object> but I'm not sure what you'd want that. Commented Jun 8, 2016 at 13:27
  • 1
    Yes, your real problem resides in what you are trying to accomplish, not trying to reproduce bad coding practice in a different language :/ Commented Jun 8, 2016 at 13:32

5 Answers 5

2

You need to get a different IEnumerable whose elements have been cast like so:

IEnumerable<object> Enumers
{
    get { return this.ts.Cast<object>(); }
}

In C# there is something called boxing which I guess is how this will work for T being structs, though I didn't check.

Sign up to request clarification or add additional context in comments.

Comments

2

IEnumerable<T> inherits from IEnumerable, so depending on what you actually need, you have two options: Change your return type to IEnumerable

IEnumerable Enumers { get; }

Or cast all elements of your collection to object

public IEnumerable<object> Enumers
{
    get { return ts.Cast<object>(); }
}

Comments

0

There is no wildcard <?> in C# like in Java.

But with the usage of dynamic and language specific stuff you are also able to handle such problems: see (C# Generics: wildcards)

Like other user pointed out you can use the Cast functionality for solving your problem.

public IEnumerable<object> Enumers
{
    get { return ts.Cast<object>(); }
}

Comments

0

In the .NET CLR, type parameters are handled very differently depending on whether it's a reference type (e.g. object) or a value type (e.g. double). Essentially, all referene type variables are pointers of the same size, while all value type variables are exactly the size of the value type.

In fact, the CLR will generate a single runtime type applicable for all reference types you can specify for a type parameter, but individual runtime types for every value type you use as the type parameter.

In Java there is no such thing as generics for primitive types, while in .NET there's no such thing as an explicitly boxed version of a value type. Java has double (primitive type) and Double (reference type), but C# only has double (value type). The only way to store a value type as reference is to use the type object or an interface type the particular value type implements.

Comments

0

In case if you can modify your interface I, I would recommend you to do this:

public interface I<T>
{
    IEnumerable<T> Enumers { get; }
}

because of boxing. If not, you can do this:

public class A<T> : I
{
     IEnumerable<T> items;

     public IEnumerable<object> Enumers
     {
         get
         {
            foreach(var item in items)
            {
                yield return (object)item;
            }
         }
     }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.