2012-01-05 31 views
1

这是代码:如何从基类访问私有阴影常量?

void Main() 
{ 
    Base.Title.Dump("Base");    // displays "Base Title" 
    Child.Title.Dump("Child");   // displays "Base Title" 

    Base baseClass = new Base(); 
    Base childClass = new Child();  // "InvalidOperationException" would be thrown 
} 

class Base { 
    public const string Title = "Base Title"; 

    public string ClassTitle { get; set; } 

    public Base() { 
     Type type = this.GetType(); 

     type.GetFields() 
      .First(item => item.Name == "Title") 
      .GetValue(this).Dump(); 
    } 
} 

class Child : Base { 
    private new const string Title = "Child Title"; 
} 

的 “InvalidOperationException异常” 异常在基本构造函数抛出。

+5

如果派生类型试图去做的第一件事是摆脱它,也许会重新考虑这个事物是一个常量。 – 2012-01-05 16:04:56

+3

基类应该不知道它的子类。如果你是编码,否则你违反开放 - 闭合原则。 – 2012-01-05 16:10:10

+0

我正在对旧代码进行维护,我试图不触及数百个子类。 – acermate433s 2012-01-05 16:19:46

回答

1

如果你想在派生类的标题,您需要要么使孩子类的标题公开 或粗暴地砸开它的私有成员是这样的:

Console.WriteLine((type.GetFields(
    System.Reflection.BindingFlags.NonPublic | 
    System.Reflection.BindingFlags.Static) 
    .First(item => item.Name == "Title")) 
    .GetValue(this)); 

如果你想在基类标题,那么你的行:

Type type = this.GetType(); 

当你想要的基类型获取派生类型。

试试这个:

Type type = typeof(Base); 
+0

这使我找到了正确的答案。由于Title字段在Base类中是公共的,但在Child类中是私有的,所以我还必须检查BindingFlags.Public字段。谢谢! – acermate433s 2012-01-05 20:57:04

1

试试这个

(type.GetFields().First(item => item.Name == "Title")).GetValue(this); 
+0

它会抛出相同的异常 – acermate433s 2012-01-05 16:23:23

+0

你是对的。思考它我会在基类中使用只读属性而不是常量,并通过基类构造函数传递属性的值。可选地使用只读字段。 – 2012-01-05 16:43:07

1

访问它只是找到,如果你不通过反射做。

Title.Dump(); 
+0

当我实例化一个子类时,它将显示“基本标题”而不是“子标题” – acermate433s 2012-01-05 16:21:56

+0

哦,不清楚你是否需要派生值。 – BlueMonkMN 2012-01-05 16:25:44

0

根据MSDN,GetFields()默认只返回公共字段。 尝试对BindingFlags使用重载。

+0

这是GetField()的重载。如果您愿意,可以使用GetFields的重载:http://msdn.microsoft.com/en-us/library/6ztex2dc.aspx – seldary 2012-01-05 16:20:49

0

您需要使用指定私有,静态字段GetFields的过载:

type.GetFields(BindingFlags.Static | BindingFlags.NonPublic) 
      .First(item => item.Name == "Title") 
      .GetValue(null).Dump(); 

也就是说,这是一个非常糟糕的主意。考虑使用属性来关联元数据,而不是使用反射来访问私有常量。