简体   繁体   English

如何编写将不同类型作为参数的泛型方法?

[英]How do I write a generic method that takes different types as parameters?

I have the following extension method to add the elements in one collection to another collection: 我有以下扩展方法将一个集合中的元素添加到另一个集合:

public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> list)
{
    foreach (var item in list)
    {             
        collection.Add(item);
    }
}

This works fine if the IEnumerable list is the same type as the ICollection I'm trying to add it to. 如果IEnumerable列表与我试图将其添加到的ICollection的类型相同,则此方法可以正常工作。 However, if I have something like this: 但是,如果我有这样的事情:

var animals = new List<Animal>();
var dogs = new List<Dog>(); // dog is a subclass of animal
animals.AddRange(dogs); // this line has a compiler error, it can't infer the type

How do I modify my extension method to be able to do something like this, if the type of the IEnumerable is a subclass (or implements the interface) of the T type? 如果IEnumerable的类型是T类型的子类(或实现接口),如何修改我的扩展方法以便能够执行此类操作?

This method will give you what you want: 这个方法会给你你想要的:

public static void AddRange<A,B>(
  this ICollection<A> collection, 
  IEnumerable<B> list)
    where B: A
{
    foreach (var item in list)
    {
        collection.Add(item);
    }
}

A couple of notes: 几个笔记:

  1. The only way that this can work is if you use a type for B that is derived from A. For example, Dog is a subclass of Animal, so AddRange will work. 唯一可行的方法是使用从A派生的B类型。例如,Dog是Animal的子类,因此AddRange将起作用。 This is enforced by the "where B: A" clause. 这由“where B:A”条款强制执行。 Without this, the ICollection.Add() call will fail due to an incompatible type for B being passed into the ICollection expecting an A. 如果没有这个,ICollection.Add()调用将失败,因为B的不兼容类型被传递到期望A的ICollection中。
  2. There's not a lot of need to restrict the type of A to anything in the Animal type hierarchy; 在Animal类型层次结构中,没有太多需要将A的类型限制为任何东西; the extension method could be used anywhere you have one type deriving from another. 扩展方法可以在任何一种类型派生自另一种类型的地方使用。
  3. This isn't really a problem of the compiler not being able to infer the types. 这不是编译器无法推断类型的问题。 Even if you explicitly passed the types for A and B everywhere, you'll still get a compiler error. 即使您在任何地方明确传递了A和B的类型,您仍然会遇到编译器错误。

You can do this: 你可以这样做:

public static void AddRange<T,T2>(this ICollection<T> collection, IEnumerable<T2> list) where T2: T {
foreach (var item in list)  {                     
    collection.Add(item);    
} }

wait for C# 4.0 or use the Linq extension method Cast : 等待C#4.0或使用Linq扩展方法Cast

List<Animal> animals = new List<Animal>();
List<Dog> dogs = new List<Dog>();
animals.AddRange(dogs.Cast<Animal>());
public static void AddRange<TA, TB>(this ICollection<TA> collection, 
                                    IEnumerable<TB> list) where TB : TA

(incorporated Craig Walker's comment) (并入Craig Walker的评论)

I would use constraint to restrict the type. 我会使用约束来限制类型。

    public static void AddRange<T, TK>(this ICollection<T> collection, IEnumerable<TK> list) where TK : T
    {
        foreach (var item in list)
        {
            collection.Add(item);
        }
    }

暂无
暂无

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

相关问题 如何为类型参数约束的泛型类型编写扩展方法? - How do I write an extension method for a generic type with constraints on type parameters? 在C#中,我如何创建一个扩展方法,该方法采用带有泛型参数的Lambda函数,Func <T, TResult> 作为参数。 - In C# how do I create an extension method that takes a lambda with generic parameters, Func<T, TResult> as a parameter. 我如何使方法泛型返回不同的类型,但接受相同类型的实例? - How do I make the method/s generic which returns different types, but accepts the same type of instance? 我如何使用RhinoMocks对三种不同类型的AssertWasCalled泛型方法? - How do I AssertWasCalled a generic method with three different types using RhinoMocks? 重载采用具有不同类型的通用列表作为参数的方法 - Overloading a method that takes a generic list with different types as a parameter 如何实现通用方法对不同的值类型进行数学计算 - How to Implement Generic Method to do Math calculations on different value types 如何创建一个以2个双精度和一个时间跨度为参数的webapi方法? - How do I create a webapi method that takes in 2 doubles and a timespan as parameters? 如何继承具有不同通用返回类型的方法 - How to Inherit a method with different generic return types 如何编写一个将枚举作为泛型并返回int值的方法 - How to write a method that takes an enum as a generic and returns the int value 如何编写一个转换以支持许多不同的页面类型? - How do I write a transformation to support many different page types?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM