2013-03-21 2 views
0

У меня есть следующие настройки:Нельзя отличить производный тип от базового типа?

struct Item { } 

class Entry : List<Item> { } 

в обобщенном классе, где я пройти Entry в качестве параметра типа, я пытаюсь получить List<Item>.Count.

я попробовал следующее уже:

var c = typeof(T).GetProperty("Count").GetMethod.Invoke(X, new object[]{}); // x is the variable in the generic class of type T! 

я также попытался

var c = (x as ICollection).Count; 
// throws Cannot cast '((Entry)X)' (which has an actual type of 'Entry') to 'System.Collections.Generic.List<Item>' 

теперь я действительно не имею ни малейшего представления о том, как получить граф :(

кода для общего класса : Идея состоит в том, чтобы иметь поле, которое запоминает конкретное начальное значение, а затем дает обратную связь, если оно было изменено.

SyncField<T> 
{ 
    T O { get; private set; } 
    T V { get; private set; } 

    public bool HasChanged 
    { 
     get 
     { 
      if (V != null && O != null) 
      { 
       var func = typeof(T).GetProperty("Count"); 
       if (func != null) 
       { 
        var oc = func.GetMethod.Invoke(O, new object[] { }); 
        var vc = func.GetMethod.Invoke(V, new object[] { }); 
        return oc != vc; // here i am trying to simply do ICollection.Count != ICollection.Count 
       } 
      } 
      return O != null && !O.Equals(V); 
     } 
    } 

}

Update: Я остановился на этом:

public bool HasChanged 
{ 
    get { return return O != null && !O.Equals(V); } 
} 

Почему? потому что Equals() Метод List<T> уже делает то, что мне нужно сказать, если они 2 разные :)

+3

Почему вы используете отражение в первую очередь? Если элемент является «Entry» или любым его подтипом, вы можете просто называть его «Count» и выполняться. – Servy

+0

Дизайн шаблона: Оформите композицию объекта над наследованием класса, почему бы вам извлечь из него, а не включать список в качестве участника? – David

+2

Пожалуйста, покажите короткий, но * полный * пример, демонстрирующий проблему. (И затем подумайте о перепроектировании, как было предложено.) –

ответ

2

Я предполагаю, что вы делаете SyncField<Entity> в другом месте.

SyncField<T> 
{ 
    T O { get; private set; } 
    T V { get; private set; } 

    public bool HasChanged 
    { 
     get 
     { 
      if (V != null && O != null && O is ICollection) 
      { 
       return ((ICollection)O).Count != ((ICollection)V).Count; 
      } 
      else 
      { 
       return O != null && !O.Equals(V); 
      } 
     } 
    } 
} 
+0

Вы правы и смешно, что это работает, потому что это не будет работайте с 'as ICollection'. Благодаря! – Nefarion

+0

@Nefarion - Я рад, что это помогло. 'return (O as ICollection) .Count! = (V as ICollection) .Count' отлично работает для меня. – Bobson

Смежные вопросы