2012-01-31 49 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