You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何遍历MyAnimals无法获取所有成员?如何无需OfType遍历全部对象?

问题解答

1)为何首次遍历无法获取所有成员?

咱们先拆解这段代码的核心逻辑:(x as Animal) 是在尝试把集合里的对象强制转换为Animal类型,但as运算符有个特点——如果转换失败(也就是当前对象根本不是Animal的子类/实现类实例),就会返回null,而你打印的是Type属性,null值自然不会输出有效内容。

你提到用MyAnimals.OfType<Zebra>()能拿到Zebra对象,这说明你的MyAnimals集合里的Zebra对象并没有继承Animal类,但Cat、Dog是明确继承了Animal的。所以当你用as Animal转换Zebra时必然失败,返回null,也就看不到它的输出;而Cat、Dog能成功转换,所以能正常打印出Type。

举个贴合你场景的代码例子:

public class Animal { public string Type { get; set; } }
public class Cat : Animal { }
public class Dog : Animal { }
public class Zebra { } // 注意:这个类没继承Animal

// 集合里的元素示例
var MyAnimals = new List<object> { new Cat{Type="Cat"}, new Dog{Type="Dog"}, new Zebra() };

这时候用x as Animal转Zebra就会得到null,自然打不出有效内容。

2)如何无需手动为每种类型使用OfType()来遍历所有对象?

想要遍历所有对象并获取类型相关信息,完全不用逐个写OfType<T>,这里给你几个实用方案:

方案一:直接获取对象的运行时类型名称

如果只是想输出每个对象的类型标识,不需要依赖Animal的Type属性,直接用GetType()获取对象的实际运行时类型即可:

foreach (var x in MyAnimals)
{
    Print(x.GetType().Name); // 会输出Cat、Dog、Zebra,每个对象的真实类型名
}

方案二:定义共同接口(推荐,更规范)

如果你的所有“动物”类型都应该具备Type属性,最规范的做法是定义一个通用接口,让所有类型都实现它:

public interface IAnimal
{
    string Type { get; }
}

public class Animal : IAnimal { public string Type { get; set; } }
public class Cat : Animal { }
public class Dog : Animal { }
public class Zebra : IAnimal { public string Type => "Zebra"; } // 实现接口

之后遍历的时候直接转换为IAnimal,所有实现了接口的对象都能成功转换并输出Type:

foreach (var x in MyAnimals)
{
    var animal = x as IAnimal;
    if (animal != null)
    {
        Print(animal.Type);
    }
}

方案三:反射获取Type属性(万不得已才用)

如果没办法修改现有类的定义,也可以用反射来读取Type属性,但这种方式性能较差,不推荐在高频场景使用:

foreach (var x in MyAnimals)
{
    var typeProp = x.GetType().GetProperty("Type");
    if (typeProp != null)
    {
        var typeValue = typeProp.GetValue(x)?.ToString();
        Print(typeValue);
    }
}

内容的提问来源于stack exchange,提问作者T.Todua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:06:31