题
我开发一个应用程序,我需要调用一个泛型类的方法,我不关心的情况下实际类型。类似下面的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这样的阵列,使用非通用基类或接口似乎是唯一的方法。
解决方案
在正常的方式来做到这将是使所述方法通用的:
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);
话虽如此,创建一个非通用接口指定类型不可知操作可能是有用的。这将在很大程度上取决于你的具体使用情况。
其他提示
我看到你只想调用一些方法不带参数......已经有针对合同:Action
public void processItems(IEnumerable<Action> actions)
{
foreach(Action t in actions)
t();
}
客户端:
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);
有没有办法,你可以省略.NET泛型实现类型参数;这是由设计。事实上,这仅可在Java中,因为它的类型擦除基于执行来实现的。
可以仅使用基本非通用接口(认为IEnumerable<T>
和IEnumerable
)。
继Jon的讯息。使得该方法的通用(模板)否定(使用<?>),用于这种功能的要求。你总是可以养活一个类型为通用类/函数和,你不知道你会需要你可以让有问题的方法/类通用以及什么类型的案件......最终用户必须提供一个类型的主叫时这样的功能或使用泛型类的代码才能编译......否则你会得到一些编译器错误。
我一直在挣扎了同样的问题,当它来到从Java移植的东西在那里我已经构造,如
if (o instanceof Collection<?>) doSoemthing((Collection<?>)o);
幸运的事实证明,一个通用的ICollection也是非通用的ICollection并且如果有人需要治疗的元素在它作为纯对象仍然有可能:
if (o is ICollection) DoSomething((ICollection)o);
这样的话,因为我们不关心实际类型集合元素,以所有我们在这里得到的是对象。 这里的说明:。如果集合是保持原始类型(INT或例如字节),然后自动装箱踢,其中可能引入的性能损失