C# 如何从列表中获取指定值<;T>;T是一个泛型类?
假设我们有一个带有泛型数组的容器类C# 如何从列表中获取指定值<;T>;T是一个泛型类?,c#,generics,reflection,C#,Generics,Reflection,假设我们有一个带有泛型数组的容器类 public class Container<T> { public T[] ObjectArray = new T[]; } public class PlayerInfo { public int level; public string playerName; public string description } public class EnemyInfo { public string ene
public class Container<T>
{
public T[] ObjectArray = new T[];
}
public class PlayerInfo
{
public int level;
public string playerName;
public string description
}
public class EnemyInfo
{
public string enemyName;
}
现在我可以想办法用反射做点什么,但也许还有另一种方法吗?好吧,如果你想从特定类型中获取特定属性,例如
EnemyInfo
中的enemyName
,对player也是如此(因此他们不会共享基类中的属性),我想你需要投下他们/检查类型,然后采取相应的行动
这样做应该可以:
foreach(var element in list)
{
if(element is EnemyInfo enemy)
{
// print out
enemy.enemyName
}
else if(element is PlayerInfo player)
{
// print out
player.playerName;
player.description;
}
}
foreach(var element in list)
{
print element.EntityName;
// Then cast if necessary for more specific types.
if(element is EnemyInfo enemy)
{
/// ...
}
else if(element is PlayerInfo player)
{
/// ...
player.description;
}
}
作为一般建议,因为敌人和玩家都有一个名字,所以要有一个基类f.e.BaseInfo,它有一个专有的名字,玩家和敌人可以从中继承,所以如果你只想得到名字,你不需要施放:
public class BaseInfo
{
public string EntityName;
}
public class PlayerInfo : BaseInfo
{
public int level;
public string description
}
public class EnemyInfo : BaseInfo
{
// Have more specific enemy stuff here....
}
然后,您可以执行以下操作:
这样做应该可以:
foreach(var element in list)
{
if(element is EnemyInfo enemy)
{
// print out
enemy.enemyName
}
else if(element is PlayerInfo player)
{
// print out
player.playerName;
player.description;
}
}
foreach(var element in list)
{
print element.EntityName;
// Then cast if necessary for more specific types.
if(element is EnemyInfo enemy)
{
/// ...
}
else if(element is PlayerInfo player)
{
/// ...
player.description;
}
}
如果您想要对象的字符串表示,一个简单且易于理解的解决方案是将其转换为JSON字符串:
foreach (var item in container.ObjectArray)
{
Console.WriteLine(JsonConvert.SerializeObject(item));
}
这将为每个项目输出一个字符串,每个字符串包含每个项目的所有属性,而不管类型如何
如果您不喜欢JSON格式,则必须决定自己的自定义格式,并编写自己的序列化程序(最终可能不得不使用反射)。但原则将保持不变。这是否回答了您的问题?我认为更好的方法是不要有无意义的超泛型容器类。如果您需要一个集合来保存
PlayerInfo
s,请声明一个集合;如果出于某种原因必须在一个位置存储多个不同类型的容器,那么可以使用一个类来保存多个类型属性(每个类型属性本身都可以是容器、字典或其他类型)。我很难想象实际场景中存储多个容器是有意义的,每个容器在一个地方都有不同的、不兼容的类型,并且仍然有意义地处理它们给出有意义的表示,并称之为;这有利于为任何对象
工作。编写一个泛型的.ToString()
,使用反射来计算所有属性值也不是很难,所以如果您不想的话,您不必为每个类都重做它。理想情况下,这会更有意义,但事实上,我有数百个类似于PlayerInfo的类,不可能逐个处理。因此,我仍然需要一种更通用的方法来实现这一点:(.对象的字符串表示不是我需要的。我需要对象中“字符串”类型的字段(例如playerName,但不是level)。