Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 运行时用new关键字标记为空的属性,但基本属性正确_C#_Serialization_Polymorphism_Overriding_New Operator - Fatal编程技术网

C# 运行时用new关键字标记为空的属性,但基本属性正确

C# 运行时用new关键字标记为空的属性,但基本属性正确,c#,serialization,polymorphism,overriding,new-operator,C#,Serialization,Polymorphism,Overriding,New Operator,关于派生类中带有属性的new关键字,我有很多问题,可能是误解。大多数文档都涉及衍生方法的new。例如: [DataContract] [KnownType(typeof(PostCategory))] public class BaseCategory : IEquatable<BaseCategory> { //... /// <summary> /// Enables access to child categories (immediate one

关于派生类中带有属性的
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; }
//...
}
[DataContract]
[知识类型(类型(后分类))]
公共类基类:IEquatable
{
//...
/// 
///允许访问子类别(直接类别)。由数据访问提供程序填写。不可序列化。
/// 
公共排序字典子项{get;set;}
//...
}
[数据合同]
[知识类型(类型(基本类别))]
公共类后类别:基本类别
{
//...
公共新SortedDictionary子项{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;
        }
    //...
    }
公共类CachedXmlCategorizationProvider:ICategorizationRepository其中T:BaseCategory,new()
{
私有只读ICacheProvider\u cacheProvider=AppServices.Cache;
私有只读字符串_file=Path.Combine(XmlProvider.DataStorePhysicalPath,typeof(T).Name,“categorization.xml”);
私人分类词典;
//...
私有SortedDictionary LoadFromDatastore()
{
如果(!DefaultsExist())
{
返回CreateDefaults();
}
var dcs=新的DataContractSerializer(typeof(SortedDictionary));
XmlDictionaryReader阅读器=
XmlDictionaryReader.CreateTextReader(新文件流(_file,FileMode.Open,FileAccess.Read),
新的XmlDictionaryReaderQuotas());
_dictionary=(SortedDictionary)dcs.ReadObject(reader,true);
/*这里!显然这填充了基类的Children属性*/
//填写儿童
foreach(字典中的var对)
{
pair.Value.Children=GetChildren(pair.Value.Id);
}
reader.Close();
返回字典;
}
//...
}
当我试图在运行时访问特定的
后分类
实例的
Children
属性时,它是
null
,并且
base.Children
被设置为由
GetChildren()
方法设置的正确的子字典

问题是,我的代码依赖于检查PostCategory.Children实例,因为它为null,所以我的代码失败了


实现我想要的(拥有一个基类并更改派生类中属性的类型)的正确方法是什么?

对于
new
关键字的继承与
virtual
override
成员的作用方式不同,因为它根本不起作用。如果通过对基类的引用访问该成员,则会访问基类的成员,并完全绕过隐藏的成员。在正确继承的情况下,如果派生类中的任何一个重写了基成员,则这种调用将继续下去

如果需要正确的行为,则需要将基本属性
设置为虚拟属性
,并在派生类中重写它


似乎您正在尝试使派生类型更具体。这可能通过使用接口和来实现。

我无法使用虚拟覆盖组合更改基本属性的类型。我们将调查协方差。。