无法使用new关键字隐藏基类的属性或字段

时间:2015-08-05 17:12:58

标签: c#

我们在某些应用程序中使用dll。应用程序无法设置该dll的类类型的对象的所有属性。 dll本身只填充其中的一些字段。

现在,由于特殊原因,我必须在一个应用程序中设置一些属性。通常,我们不会延长dll的类。在这里,我正在扩展dll的类,我正在使用" new"用于隐藏基本属性的关键字。目的是在该财产中设定价值。

基类位于另一个不同的命名空间中,

method=parallel

在扩展课程中," new"使用关键字,

namespace AnotherAssembly
{
    public abstract class AbstructHead
    {
        public Int16 Int_toHide{ get; internal set; }
        public Int16 Int_noHide { get;  set; }
        public DateTime ReadTime { get; internal set; }
    }
}

以下是观察窗口的截图

The watch window after execution of the code.

你知道,我无法使它发挥作用。这里的代码有什么问题。我如何填充数据? " ah.ReadTime"没有给我任何东西。

namespace TestingNew
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //AbstructHead ah = new AbstructHead();
            AbstructHead ah = new Assist();
            Assist ext = (Assist)ah;

            ext.Int_toHide = 20;
            ext.Int_noHide = 30;
            ext.ReadTime = new DateTime(2014, 1, 18);


            DateTime readTime = ah.ReadTime;
        }
    }

    public class Assist : AbstructHead
    {
        new public Int32 Int_toHide{ get; set; }
        new public DateTime ReadTime { get; internal set; }

    }
}

2 个答案:

答案 0 :(得分:0)

自动属性(只有get; set;的属性)在编译代码时为您生成一个字段。因此,在Assist类中,您没有设置基类的值,您只需设置新字段的值。

要使这项工作,您应该自己实现该属性:

public class Assist : AbstructHead
{
    new public Int32 Int_toHide
    { 
        get { return base.Int_toHide; }
        set { base.Int_toHide = value; }
    }
}

请记住,基类的属性是internal,因此只有在同一个程序集中定义Assist(或InternalsVisibleTo属性中提到)时才能使用此属性。

作为最后的手段,您可以选择使用反射来设置基值。

修改

在回复评论时,以下是使用反射访问该属性的方法:

PropertyInfo property = typeof(AbstructHead).GetProperty("Int_toHide", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (property == null) 
{
    throw new ApplicationException("This version of AbstructHead does not have an Int_toHide property");
}

property.SetValue(this, value, null);

我不知道你的最终目标是什么,通常成员是内部的,并且使用反射通常不是最好的方法,所以不要说我没有警告你:/

答案 1 :(得分:0)

使用new不会替换基类中的属性,它只会隐藏它。只有你有一个类型为派生类的引用才能看到它。例如,如果你有这个:

public class A
{
    private string _foo = "Foo";
    public string Foo
    {
        get
        {
            return _foo;
        }

        private set
        {
            _foo = value;
        }
    }
}

public class B : A
{
    private string _foo = "Bar";
    public new string Foo
    {
        get
        {
            return _foo;
        }

        set
        {
            _foo = value;
        }
    }
}

你这样做:

A foo = new B();
Console.WriteLine(foo.Foo);     // Foo

然后,这将在类Foo上调用A,因为foo的类型为A(即使它包含{{1}类型的对象})。要查看B属性,您必须将其投射:

new

现在因为B fooB = (B)foo; Console.WriteLine(fooB.Foo); // Bar Foo的设置者被标记为私有,所以无法访问它。在A上设置Foo不会更改B中的值。您的A对象实际上有两个完全独立的属性,名称相同。

你可以通过反思来获得foo的setter的唯一方法。