我有一个简单的错误基类,为了这个问题的目的,一个int代表一个可能的错误值。
我从这个Error基类派生了一个ErrorMultiple类,它有一个int列表,这样我就可以保存多个错误值。
我希望将一个Event类包含在Error基类的单个实例中。
所以我创建了一个Event实例并将其传递给许多方法。其中一个决定“哦不。我们发现要报告多个错误。“
如何编写代码以使我的Event对象丢弃它的Error基类实例,并通过Event.ReplaceErrorObjWithMultipleErrorObj()将其替换为ErrorMultiple类的实例
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#语法中是垃圾。我不知道如何声明对可替换对象实例的引用。
答案 0 :(得分:1)
问题#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 ++。
建议阅读: