Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the equivalent of Java wildcards in C# generics

Tags:

I'm developing an application where I the need to invoke a method of a generic class and I don't care about the instances actual type. Something like the following Java code:

public class Item<T>{   private T item;    public doSomething(){...} }  ... public void processItems(Item<?>[] items){  for(Item<?> item : items)    item.doSomething(); } 

At the time I was on a hurry, so I solved my problem by defining a interface with the methods I needed to invoke and made the generic class implement it.

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

This workaround works fine, but I'd like to know what is the correct way to achieve the same behavior.

EDIT:

I forgot to refer that the caller of processItems doesn't know the actual types. Actually the idea was that the array passed as argument to processItems could contain intermixed types. Since its not possible to have such an array in .Net, using a non generic base class or interface seems to be the only way.

like image 346
jassuncao Avatar asked Feb 09 '09 11:02

jassuncao


People also ask

What is wild card type in Java?

In the Java programming language, the wildcard ? is a special kind of type argument that controls the type safety of the use of generic (parameterized) types. It can be used in variable declarations and instantiations as well as in method definitions, but not in the definition of a generic type.

How do wildcards work in Java?

Wildcards in Java are basically the question marks which we use in generic programming, it basically represents the unknown type. We use Java Wildcard widely in situations such as in a type of parameter, local variable, or field and also as a return type.

Can wildcard types be replaced by any type?

Due to extensive capture conversion, in most places, compiler treats wildcards as if they are type variables. Therefore indeed programmer can replace wildcard with type variables in such places, a sort of manual capture conversion.


2 Answers

The normal way to do this would be to make the method generic:

public void ProcessItems<T>(Item<T>[] items) {   foreach(Item<T> item in items)     item.DoSomething(); } 

Assuming the caller knows the type, type inference should mean that they don't have to explicitly specify it. For example:

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

Having said that, creating a non-generic interface specifying the type-agnostic operations can be useful as well. It will very much depend on your exact use case.

like image 127
Jon Skeet Avatar answered Sep 30 '22 05:09

Jon Skeet


I see that you only want to invoke some method with no parameters... there's already a contract for that: Action.

public void processItems(IEnumerable<Action> actions) {   foreach(Action t in actions)     t(); } 

Client:

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); 
like image 37
Amy B Avatar answered Sep 30 '22 04:09

Amy B