C#继承的字段值与基类混淆';字段值
本文关键字:字段 继承 基类 | 更新日期: 2023-09-27 18:21:52
我正在尝试将"MyClass"的实例序列化到XML文件中,一次一个。每个实例都有一个名为"ID"的int属性。目标文件已经有一些相同类型的项,我将在这些项之后添加新项。我希望被插入实例的ID值比XML中最大的现有项高1。
我有以下通用类:
public class ContentDataManager<T> where T : MyBaseClass
{
private static string _contentLocation = "Content/Data/";
private const string DEFAULT_FILEPATH = "data.xml";
public static int GetNextId(string filepath = DEFAULT_FILEPATH)
{
var allData = DeserializeAll(filepath);
int largestId = 0;
foreach (T data in allData)
{
if (data.ID > largestId)
{
largestId = data.ID;
}
}
return largestId + 1;
}
//...
}
我这样使用这个类:
public class MyClass : MyBaseClass
{
public string Name;
public float Size;
public new int ID;
public static MyClass CreateNew(string name, float size)
{
MyClass newClass = new MyClass();
newClass.Name = name;
newClass.Size = size;
newClass.ID = ContentDataManager<MyClass>.GetNextId(DefaultFilepath);
return newClass;
}
MyBaseClass看起来像这样:
public abstract class MyBaseClass
{
//...
[ContentSerializerIgnore]
public int ID = 0;
}
问题是,在ContentDataManager.GetNextId(…)方法的foreach循环中,有一个if语句实际上无法正常工作。调试时,我添加了两个手表:"data"answers"data.ID"下面是有趣的部分:对"data"的监视显示ID属性的值为1。同时,"data.ID"属性显示值为0。
我确信这个错误与继承有关。我应该如何更改代码,以免出现此错误?
您需要删除此行:
public new int ID;
根据您所展示的,在派生类中不需要单独的ID,基本ID就可以了。当然,如果您想序列化ID,也需要删除ContentSerializerIgnore
属性。
这里有一个示例来演示,当您使用"new"关键字声明成员时,您将创建与基类成员完全无关的成员。
using System;
namespace Test
{
abstract class Base
{
public string Data;
}
class Derived : Base
{
// this is a separate field, has nothing in common with the base class field but name
new public string Data;
}
class Program
{
static void Main(string[] args)
{
Derived test = new Derived();
//Let's set the Data field in the derived class
test.Data = "Derived";
//Now let's set this field in the base class
Base cast = test;
cast.Data = "Base";
//We can see that the feild in the derived class has not changed
//This will print 'Derived'
Console.WriteLine(test.Data);
// Just to make sure that a new object has not been constructed by a miracale
// let's pass our object to a function that will display the Data field from
// the base class
Test(test);
}
static void Test(Derived test)
{
// When called from the Main above this will print 'Base'
Console.WriteLine(((Base)test).Data);
}
}
}
问题是您已经指定了where T : MyBaseClass
。这意味着data
foreach循环变量的类型将是MyBaseClass
。因此,data.ID
的唯一可访问值将是基类的版本。
看看这篇文章。
您必须将类型转换data
键入为类型MyClass
,或者始终使用基类ID
字段(这是zespri建议的)。