свойство, помеченное новым ключевым словом, пустое во время выполнения, но базовое свойство является правильным - PullRequest
1 голос
/ 02 апреля 2012

У меня довольно много проблем, возможно, недоразумений с ключевым словом new со свойствами в производных классах. Большая часть документации касается new для производных методов. Например:

[DataContract]
[KnownType(typeof(PostCategory))]
public class BaseCategory : IEquatable<BaseCategory>
{
//...

    /// <summary>
    /// Enables access to child categories (immediate ones). Filled in by data access provider. Not serializable.
    /// </summary>
    public SortedDictionary<string, BaseCategory> Children { get; set; }
//...
}

[DataContract]
[KnownType(typeof(BaseCategory))]
public class PostCategory : BaseCategory
{
//...
    public new SortedDictionary<string, PostCategory> Children { get; set; }
//...
}

Тогда в моей реализации репозитория данных у меня есть общая реализация для всех классов, которые являются производными от BaseCategory. Я делаю это:

    public class CachedXmlCategorizationProvider<T> : ICategorizationRepository<T> where T : BaseCategory, new()
    {
        private readonly ICacheProvider _cacheProvider = AppServices.Cache;
        private readonly string _file = Path.Combine(XmlProvider.DataStorePhysicalPath, typeof (T).Name, "categorization.xml");
        private SortedDictionary<string, T> _dictionary;

    //...
        private SortedDictionary<string, T> LoadFromDatastore()
        {
            if (!DefaultsExist())
            {
                return CreateDefaults();
            }

            var dcs = new DataContractSerializer(typeof (SortedDictionary<string, T>));
            XmlDictionaryReader reader =
                XmlDictionaryReader.CreateTextReader(new FileStream(_file, FileMode.Open, FileAccess.Read),
                                                     new XmlDictionaryReaderQuotas());

            _dictionary = (SortedDictionary<string, T>) dcs.ReadObject(reader, true);
/* HERE! Apparently this fills in the Children property of the base class */
            // fill in Children
            foreach (var pair in _dictionary)
            {
                pair.Value.Children = GetChildren(pair.Value.Id);
            }
            reader.Close();
            return _dictionary;
        }
    //...
    }

и когда я пытаюсь получить доступ к свойству Children определенного экземпляра PostCategory во время выполнения, это null, а base.Children устанавливается в правильный словарь для детей, как установлено методом GetChildren().

Дело в том, что мой код основан на проверке экземпляра PostCategory.Children, и, поскольку он нулевой, мой код не работает.

Как правильно достичь желаемого (иметь один базовый класс и изменить тип свойства в производном классе)?

1 Ответ

3 голосов
/ 02 апреля 2012

Наследование для ключевого слова new не работает так же, как virtual override членов, поскольку оно не функционирует вообще.Если вы обращаетесь к члену через ссылку на базовый класс, доступ к члену базового класса происходит, и скрытый член полностью игнорируется.В случае правильного наследования вызов такого рода приведет к выходу из производных классов, если какой-либо из них переопределит базовый член.

Если вам нужно правильное поведение, вам нужно задать базовое свойство virtual и override это в производном классе.

Кажется, что вы пытаетесь сделать производный тип более конкретным.Это может быть достигнуто с использованием интерфейсов и ко-дисперсии .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...