如何在运行时将基类的实例替换为派生实例
本文关键字:实例 替换 派生 基类 运行时 | 更新日期: 2023-09-27 18:21:40
我有一个简单的Error基类,为了这个问题的目的,它有一个表示可能的错误值的int。
我有一个从这个Error基类派生的ErrorMultiple类,它有一个int列表,这样我就可以保存多个错误值。
有一个Event类,我希望它是Error基类的一个实例。
因此,我创建了一个Event实例,并将其传递给许多方法。其中一个决定"哦,不。我们发现有多个错误需要报告。"
我如何编写代码来让我的Event对象放弃它的Error基类实例,并通过Event将其替换为ErrorMultiple类的实例。ReplaceErrorObjWithMultipleErrorObj()
public class Error
{
protected int ErrorNo;
}
public class ErrorMultiple : Error
{
Protected List<int> MultipleErrorNos;
}
public class Event
{
Error * errorObject;
}
Public Event()
{
errorObject = new Error();
}
void Event.ReplaceErrorObjWithMultipleErrorObj()
{
errorObject = new ErrorMultiple();
}
当然,在真正的C#语法中,Event声明是垃圾。我不知道如何声明对可替换对象实例的引用。
Issue#01-值类型和引用类型在C++中,对象是值类型,即其组件的结构。要引用内存中的值,可以使用指针。C#不是这样的。在C#中,对象默认情况下是引用,就对象而言,没有值类型。(为了简化这件事,这有点像谎言)
这意味着在C#中:
ErrorClass error = new ErrorClass();
这在C++中是等效的吗:
ErrorClass* error = new ErrorClass();
然而,关键的区别在于,没有办法像在C++中取消引用指针那样取消引用C#引用。
此外,这在C#中:
error.ErrorNumber = 0;
相当于C++中的这个:
error->ErrorNumber = 0;
实际上,正在发生的事情是,所有的指针魔法都对用户隐藏起来,以防止指针错误,并确保指针管理不会干扰托管语言的垃圾收集(一种在对象处理完后删除对象的系统,即对象超出范围)。
问题#02-语法在C#中,编译器与C++有很大不同。它更智能,也不那么严格,尽管它缺少一些功能,比如真正的定义和宏。
首先,类必须在一个块中完全包含其所有字段和方法,不能声明类的基本结构,然后再声明事物的定义。即,你不能这样做:
class ErrorClass { public: void PrintError(); }
void ErrorClass::PrintError() { printf("error"); }
因为方法的定义必须在类的主体中,比如:
class ErrorClass { public void PrintError() { Console.Write("error"); } }
然而,在使用函数之前,您不必声明函数的名称,编译器不一定按照编写代码的顺序读取代码。
总之,我将用正确的C#格式重写您的代码,这样您就可以看到事情应该是什么样子:
public class Error
{
protected int ErrorNo;
}
public class ErrorMultiple : Error
{
protected List<int> MultipleErrorNos = new List<int>();
}
public class Event
{
Error errorObject = new Error();
public void MultiplyErrors()
{
errorObject = new ErrorMultiple();
}
}
请注意,首先,错误号无法读取,因为它们受到保护,其次,C#有一个基于异常的系统,使用try、catch、finally和throw语句,类似于更现代的C++。
建议阅读:
- 引用类型:http://msdn.microsoft.com/en-us/library/490f96s2(v=vs.100).aspx
- 值类型:http://msdn.microsoft.com/en-us/library/s1ax56ch(v=vs.100).aspx
- 类别:http://msdn.microsoft.com/en-us/library/vstudio/x9afc042(v=vs.100).aspx
- 例外情况:http://msdn.microsoft.com/en-us/library/ms173160(v=vs.100).aspx