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。

我确信这个错误与继承有关。我应该如何更改代码,以免出现此错误?

C#继承的字段值与基类混淆';字段值

您需要删除此行:

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建议的)。