[英]How to save differently-typed values without converting them and thus losing their specific fields/methods in C#?
I'm trying out C# for the first time, so I apologize if this has a simple solution or if the language simply does not allow it.我是第一次尝试 C#,所以如果这有一个简单的解决方案或者语言根本不允许这样做,我深表歉意。
I'll simplify my problem to the best of my ability - Imagine I have the following classes:我会尽我所能简化我的问题——想象一下我有以下课程:
public class Animal
{
public bool isAlive = true;
public List<Animal> friends;
}
public class Dog : Animal
{
public string Bark()
{
return "Woof!";
}
}
public class Cat : Animal
{
public bool hatesMe = true;
}
public class GoldenRetriever : Dog
{
public bool greatForFamilies = true;
}
Now, the following code:现在,以下代码:
var Chuck = new GoldenRetriever();
var Stripey = new Cat();
Chuck.friends.Add(Stripey);
var myVar1 = Stripey.hatesMe; //fine
var myVar2 = Chuck.friends[0].hatesMe; //error
I know that when I added Stripey to Chuck's friends list, Stripey was converted to an Animal and lost its Cat members - my problem is: how can I have a list/array/collection of different types, without them losing their specific members?我知道当我将 Stripey 添加到 Chuck 的朋友列表时,Stripey 被转换为 Animal 并失去了它的 Cat 成员 - 我的问题是:我怎样才能拥有不同类型的列表/数组/集合,而不会失去他们的特定成员?
Thanks in advance!提前致谢!
Actually you are not losing any Data , while storing it in its base type.实际上,您不会丢失任何 Data ,而是将其存储在其基本类型中。 To access the given data, you need to convert it to the data type which inherits the base type.要访问给定的数据,您需要将其转换为继承基类型的数据类型。 In your case you need to cast it to Cat
in order to access the hatesMe
field.在您的情况下,您需要将其转换为Cat
才能访问hatesMe
字段。 This would look something like the code below.这看起来像下面的代码。
var myVar2 = ((Cat)Chuck.friends[0]).hatesMe;
In simple words, when storing an object in a datatype which it implements or inherits, you are only hiding its other members.简而言之,当将对象存储在它实现或继承的数据类型中时,您只是隐藏了它的其他成员。
Twenty is right.二十是对的。 You need need cast the class Animal to Cat before you can access the 'hatesMe' field:在访问“hatesMe”字段之前,您需要将类 Animal 转换为 Cat:
var myVar2 = ((Cat)Chuck.friends[0]).hatesMe;
But if the type of Animal is unknown you could work with virtual/override properties:但是,如果 Animal 的类型未知,您可以使用虚拟/覆盖属性:
public class Animal
{
public bool isAlive = true;
public List<Animal> friends;
public virtual bool HatesMe
{
get
{
return false;
}
}
}
public class Dog : Animal
{
public string Bark()
{
return "Woof!";
}
}
public class Cat : Animal
{
public override bool HatesMe
{
get
{
return true;
}
}
}
public class GoldenRetriever : Dog
{
public bool greatForFamilies = true;
}
Now the property 'HatesMe' works with all classes which are inherited from Animal:现在属性“HatesMe”适用于从 Animal 继承的所有类:
var Chuck = new GoldenRetriever();
var Stripey = new Cat();
Chuck.friends.Add(Stripey);
var myVar1 = Stripey.hatesMe; //fine
var myVar2 = Chuck.friends[0].HatesMe; //fine
In case the type of Animal is unknown but the given class structure shouldn't be touched you could access the 'hatesMe' field through reflection using the dynamic keyword:如果 Animal 的类型未知但给定的类结构不应被触及,您可以使用dynamic关键字通过反射访问“hatesMe”字段:
dynamic Stripey = new Cat();
bool b = Stripey.hatesMe; //fine
Be aware, accessing fields through reflection is slow.请注意,通过反射访问字段很慢。 Furthermore if you rename the 'hatesMe' field without adapting the dynamic code, the code will throw an exception.此外,如果您在不调整动态代码的情况下重命名“hatesMe”字段,代码将抛出异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.