简体   繁体   English

Java列表 <?> 在C#中

[英]Java List<?> in C#

Is there some way to get a java List<?> in C#? 有什么方法可以在C#中获取Java List<?>

I need to get a IEnumerable<T> , where T can be either a class (string), or a struct (int, double...). 我需要获得IEnumerable<T> ,其中T可以是class (字符串)或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> . 由于无法从IEnumerable<T>IEnumerable<object> ,因此它在运行时崩溃。

Any ideas? 有任何想法吗?

You need to get a different IEnumerable whose elements have been cast like so: 您需要获取一个其他IEnumerable,其元素的类型如下:

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. 在C#中,有一种叫做Boxing的东西,我猜想这对于T结构是如何工作的,尽管我没有检查。

IEnumerable<T> inherits from IEnumerable , so depending on what you actually need, you have two options: Change your return type to IEnumerable IEnumerable<T>继承自IEnumerable ,因此根据您的实际需要,您有两个选择:将返回类型更改为IEnumerable

IEnumerable Enumers { get; }

Or cast all elements of your collection to object 或将集合中的所有元素都转换为object

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

There is no wildcard <?> in C# like in Java. 像Java中一样,C#中没有通配符<?>

But with the usage of dynamic and language specific stuff you are also able to handle such problems: see ( C# Generics: wildcards ) 但是,通过使用dynamic语言和特定于语言的内容,您还可以处理此类问题:请参阅( C#泛型:通配符

Like other user pointed out you can use the Cast functionality for solving your problem. 就像其他用户指出的那样,您可以使用Cast功能来解决您的问题。

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

In the .NET CLR, type parameters are handled very differently depending on whether it's a reference type (eg object ) or a value type (eg double ). 在.NET CLR中,类型参数的处理方式非常不同,具体取决于它是引用类型(例如object )还是值类型(例如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. 实际上,CLR会生成一个单一的运行时类型,该运行时类型适用于您可以为类型参数指定的所有引用类型,但是对于用作类型参数的每种值类型,其运行时类型都是单独的。

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中,没有诸如原始类型的泛型之类的东西,而在.NET中,没有诸如值类型的显式盒装版本之类的东西。 Java has double (primitive type) and Double (reference type), but C# only has double (value type). Java具有double (原始类型)和Double (引用类型),但是C#仅具有double (值类型)。 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. 将值类型存储为引用的唯一方法是使用类型object或特定值类型实现的接口类型。

In case if you can modify your interface I , I would recommend you to do this: 如果可以修改interface I ,我建议您这样做:

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;
            }
         }
     }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM