2012-01-31 5 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 문이 있습니다. pr 오케이. 디버깅 할 때 '데이터'와 '데이터'라는 두 개의 시계를 추가했습니다. 재미있는 부분이 있습니다 : '데이터'의 시계는 ID 속성의 값이 1임을 보여줍니다. '데이터 .ID '속성은 0 값을 표시합니다.

나는이 오류가 상속과 관련되어 있음을 확신합니다. 이 오류가 발생하지 않도록 코드를 어떻게 변경해야합니까? 당신은 잘 할 것 파생 클래스에서 별도의 ID,베이스 하나에 대한 필요가 없습니다 보여 어떤에서

public new int ID; 

:

+2

왜'new' 연산자를 사용하여 MyClass에서'MyBaseClass'의'ID '를 숨기고 있습니까? 이 변수는 공개되어 있으며 MyClass에 의해 상속됩니다. –

답변

2

당신은이 줄을 제거해야합니다. 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

1

문제는 where T : MyBaseClass으로 지정되었습니다. 즉, data foreach 루프 변수는 MyBaseClass입니다. 따라서 data.ID의 유일한 접근 가능한 값은 기본 클래스의 버전입니다.

See this write-up about it.

당신이 중 하나를 입력 할 필요가 있습니다 유형 MyClass 수 또는 항상 (zespri이 시사하는 것입니다) 기본 클래스 ID 필드를 사용하는 data을 캐스팅.

+1

감사합니다. =) –

+1

링크를 제공해 주셔서 감사합니다. C#은 아름답습니다 .--) – Marton

+0

@ zespri, Marton : 환영합니다! –