简体   繁体   English

如何在不转换它们的情况下保存不同类型的值,从而在 C# 中丢失它们的特定字段/方法?

[英]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.

相关问题 C# class inheritance 带有 ScriptableObject UnityEvents 和不同类型的 UnityActions - C# class inheritance with ScriptableObject UnityEvents and differently-typed UnityActions C# - 保存键入的值 - C# - Save typed values 如何在不从Expression.Convert转换为C#的情况下获取可为空值(字段)的Expression? - How to get Expression for Nullable values ( fields ) without converting from Expression.Convert in C#? 将数据存储在列表中而不丢失(C#) - Storing data in a list without losing them (C#) 如何在C#Mongodb强类型驱动程序中从文档加载特定字段 - How to load specific fields from document(s) in C# Mongodb strongly typed driver 如何在不知道特定单词的情况下替换它们 C# - How to replace specific words, without knowing them C# 如何在 C# 中访问匿名类型 JArray 的字段? - How can i access fields of anonymous typed JArray in C#? 如何根据 C# 中的泛型 class 中的类型以不同方式实现方法? - How to implement methods differently depending on type in a generic class in C#? C#将字符串数据表示形式转换为类型 - C# converting string data representation to typed 在C#中获取更改的列宽以保存值并恢复它们 - Get changed columns width in c# to save values and restore them
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM