如何使用“as”检查对象是否属于参数传递的类型?

时间:2016-07-21 10:26:51

标签: c# generics

我有一个不同类型的对象列表;它们可以是柠檬,草莓,葡萄。他们都继承了水果。他们还可以实现ISour,IGrowOnTree等接口。

现在,我想编写一个方法,从所述列表中获取可以转换为特定类型的所有实例。

我现在所做的是获取所有元素并在我的调用函数中本地过滤它们:

List<Fruit> myFruits = fruitBasket.GetAllTheFruits();
List<ISour> mySourFruit = new List<ISour>();
foreach (var fruit in myFruit)
{
    var sourFruit = fruit as ISour;
    if (sourFruit != null)
        mySourFruit.Add(sourFruit);
}

我将这个逻辑移到我的篮子里,所以我不必一直重写过滤器。我能够用泛型来做到这一点,比如:

public function List<T> GetFruits<T>() where T : class
{
    List<T> result = new List<T>();
    foreach (var fruit in this._allFruits)
    {
        var fruitAsT = fruit as T;
        if (fruitAsT != null)
            result.Add(fruitAsT);
    }
    return result;
}

为了论证,是否可以用以下形式写出:

public function List<Fruit> GetFruits(Type type)

所以不要打电话:

var myFruits = basket.GetFruits<ISour>();

我宁愿打电话:

var myFruits = basket.GetFruits(typeof(ISour))

或类似的东西(所以,将类型作为参数传递而不是使用泛型)?

2 个答案:

答案 0 :(得分:1)

如果没有泛型,您必须使用Type上提供的各种实例方法。在这种情况下Type.IsInstanceOfType是最明显的:

public List<Fruit> GetFruits(Type type)
{
    var result = new List<Fruit>();

    foreach (var fruit in this._allFruits)
    {
        if (type.IsInstanceOfType(fruit))
        {
            result.Add(fruit);
        }                            
    }
    return result;
}

答案 1 :(得分:0)

您可以保留泛型解决方案并传入结果列表以帮助编译器确定适用的类型:

namespace FruitListTest
{
    class Fruit { }
    class Apple : Fruit { }

    class Program
    {
        static List<Fruit> fruitList = new List<Fruit>();

        public static void GetSpecificFruits<specificFruit>(List<specificFruit> specificFruits) 
            where specificFruit : Fruit
        {
            foreach (var fruit in fruitList)
            {
                var fruitAsT = fruit as specificFruit;
                if (fruitAsT != null)
                    specificFruits.Add(fruitAsT);
            }
        }

        static void Main(string[] args)
        {
            List<Apple> applesInFruits = new List<Apple>();
            GetSpecificFruits(applesInFruits);
        }
    }
}

这个解决方案可以通过多种方式进行美化:一个可以返回列表以简化链接等;一个可以返回数字,或布尔值(那里的任何苹果?)。人们可以传递两个参数(源列表也是如此)以具有独立功能。可以将两个参数中的任何一个作为this参数,以便可以进行fruits.GetSpecificFruits(appleList)appleList.FillFrom(fruitList)之类的调用。如果通用水果列表始终相同,则呼叫可以归结为appleList.Fill()(从fruitList隐式填充),这似乎很优雅。