C# C泛型中Java通配符的等价物是什么

C# C泛型中Java通配符的等价物是什么,c#,generics,wildcard,C#,Generics,Wildcard,我正在开发一个应用程序,其中我需要调用泛型类的方法,而不关心实例的实际类型。类似于以下Java代码: public class Item<T>{ private T item; public doSomething(){...} } ... public void processItems(Item<?>[] items){ for(Item<?> item : items) item.doSomething(); } 当时我很忙,所以我

我正在开发一个应用程序,其中我需要调用泛型类的方法,而不关心实例的实际类型。类似于以下Java代码:

public class Item<T>{
  private T item;

  public doSomething(){...}
}

...
public void processItems(Item<?>[] items){
 for(Item<?> item : items)
   item.doSomething();
}
当时我很忙,所以我通过使用需要调用的方法定义一个接口并使泛型类实现它来解决问题

public interface IItem  
{
   void doSomething();
}

public class Item<T> : IItem {
  private T item;

  public void doSomething(){...}
}

...
public void processItems(IItem[] items)
{
 foreach(IItem item in items)
   item.doSomething();
}
这个变通方法很好,但我想知道实现相同行为的正确方法是什么

编辑:


我忘了指出processItems的调用者不知道实际的类型。实际上,这个想法是作为参数传递给processItems的数组可以包含混合类型。由于在.Net中不可能有这样的数组,因此使用非泛型基类或接口似乎是唯一的方法。

在.Net泛型实现中,您无法忽略类型参数;这是故意的。事实上,这只能在Java中实现,因为它是基于类型擦除的实现


您只能使用基本的非泛型接口,如IEnumerable和IEnumerable。

通常的方法是使方法泛型:

public void ProcessItems<T>(Item<T>[] items) {
  foreach(Item<T> item in items)
    item.DoSomething();
}
假设调用者知道类型,类型推断应该意味着他们不必显式地指定它。例如:

Item<int> items = new Item<int>(); // And then populate...
processor.ProcessItems(items);

话虽如此,创建一个指定类型无关操作的非泛型接口也很有用。这在很大程度上取决于您的具体用例。

请继续阅读Jon的文章。将方法泛型化为一个模板,就不需要使用。您始终可以将类型馈送到泛型类/函数中,对于不知道需要什么类型的情况,您也可以将有问题的方法/类设置为泛型。。。最终,用户必须在调用此类函数或使用泛型类时提供类型,以便代码能够编译。。。否则您将得到一些编译器错误。

我发现您只想调用一些没有参数的方法。。。已经有了一个合同:行动

客户:

List<Animal> zoo = GetZoo();
List<Action> thingsToDo = new List<Action>();
//
thingsToDo.AddRange(zoo
  .OfType<Elephant>()
  .Select<Elephant, Action>(e => e.Trumpet));
thingsToDo.AddRange(zoo
  .OfType<Lion>()
  .Select<Lion, Action>(l => l.Roar));
thingsToDo.AddRange(zoo
  .OfType<Monkey>()
  .Select<Monkey, Action>(m => m.ThrowPoo));
//
processItems(thingsToDo);

当涉及到从Java移植东西时,我也遇到了同样的问题,在Java中我有类似的结构

if (o instanceof Collection<?>) doSoemthing((Collection<?>)o);
这样,因为我们不关心集合中元素的实际类型,所以这里得到的都是对象。
这里需要注意的是:如果集合中包含int或byte等基元类型,则自动装箱可能会带来性能损失。

Blargh,几秒钟太早了。:是啊,也打我。你能用调用者的例子来编辑吗?Jon,你在这里写java吗?
if (o instanceof Collection<?>) doSoemthing((Collection<?>)o);
if (o is ICollection) DoSomething((ICollection)o);