我们在某些应用程序中使用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; }
}
}
以下是观察窗口的截图
你知道,我无法使它发挥作用。这里的代码有什么问题。我如何填充数据? " 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; }
}
}
答案 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的唯一方法。