2012-01-31 47 views
1

我想序列化的情况下,‘MyClass的’到一个XML文件,一次一个。每个实例都有一个名为'ID'的int属性。目标文件已经有一些相同类型的项目,并且在这些项目之后追加新项目。我希望待插入实例的ID值比XML中最大的现有项目高1。C#继承字段值到混合了基类的字段值

我有以下的通用类:

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语句实际上不起作用operly。当我调试,我添加了两个表:“数据”和“data.ID” 这里了有趣的部分:为“数据”的手表显示,ID属性的值是1。在森那一次,“数据.ID”属性显示为0

值我敢肯定,这个错误是与遗传有关。我应该如何更改我的代码,以便不会出现此错误?

+2

你为什么要瞒着'MyBaseClass'了'ID'在'使用'new'操作MyClass'?该变量是公共的,并由你的'MyClass'继承。 – 2012-01-31 01:17:34

回答

2

您需要删除此行:

public new int 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);    
     } 
    } 
} 
+0

谢谢,这解决了这个问题。当我尝试不同的方法时,藏起来就是一个剩余物。在您建议的更改后完美地工作。 – Marton 2012-01-31 01:28:50

1

问题是,您已指定where T : MyBaseClass。这意味着data foreach循环变量将是MyBaseClass类型。所以data.ID的唯一可访问值将是基类的版本。

See this write-up about it.

你必须两种类型的投dataMyClass型或总是使用基类ID场(这是什么zespri建议)。

+1

谢谢你找到了写了=) – 2012-01-31 01:29:12

+1

感谢您的链接,C#是美丽:-) – Marton 2012-01-31 01:32:17

+0

@zespri,马顿:不客气! – 2012-01-31 15:50:15