Silverlight反编译系列二常见代码(自动生成属性CompilerGenerated,代码)
在Silverlight有一些编译后自动生成的代码,最常见的是CompilerGeneratedAttribute和DebuggerNonUserCodeAttribute,下面介绍一下这俩种属性
1.CompilerGeneratedAttribute 自动属性
使用自动属性后,你可以不用手工声明一个私有成员变量以及编写get/set逻辑,取而代之的是,编译器会自动为你生成一个私有变量和默认的get/set 操作。系统为你产生的私有变量在IDE中,你是看不到的,
如 public string ClassName { get; set; }
上面的代码我们编译后,再用 Reflector 反编译后,我们可以看到上述代码中的属性变成了如下代码:这个编译器给我们产生的私有变量,显然不是那么容易重名的。
[CompilerGenerated]
private string <ClassName>k__BackingField;
public string ClassName
{
[CompilerGenerated]
get
{
return this.<ClassName>k__BackingField;
}
[CompilerGenerated]
set
{
this.<ClassName>k__BackingField = value;
}
}
你可以看出private string <ClassName>k__BackingField中的ClassName是你定义的属性。编译系统会自动生成get,set方法。
注意:如果你只希望属性有 get 或者 set 方法,这些情况都是无法使用 自动属性的,需要你自己来书写。否则就会报如下的错误:
'ConsoleApplication1.MyClass.Name.set' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors.
但是 get 和 set 访问级别不一样,比如一个是 public,一个是 internal,则可以书写成下述方式,而不会报错误。
public int ID { get; internal set; }
此类型一般都是(极少数除外)在类对应的Xaml中定义过的变量。因此也应该从源码文件中删掉。
使用自动属性后,你可以不用手工声明一个私有成员变量以及编写get/set逻辑,取而代之的是,编译器会自动为你生成一个私有变量和默认的get/set 操作。系统为你产生的私有变量在IDE中,你是看不到的,如下图:
当然如果你希望属性中有些赋值或者取值逻辑校验,自动属性可是不适合你的。
上面的代码我们编译后,再用 Reflector 反编译后,我们可以看到上述代码中的属性变成了如下代码:这个编译器给我们产生的私有变量,显然不是那么容易重名的。
[CompilerGenerated]
private string <>k__AutomaticallyGeneratedPropertyField0;
public string Name
{
[CompilerGenerated]
get
{
return this.<>k__AutomaticallyGeneratedPropertyField0;
}
[CompilerGenerated]
set
{
this.<>k__AutomaticallyGeneratedPropertyField0 = value;
}
}
注意:如果你只希望属性有 get 或者 set 方法,这些情况都是无法使用 自动属性的,需要你自己来书写。否则就会报如下的错误:
'ConsoleApplication1.MyClass.Name.set' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors.
但是 get 和 set 访问级别不一样,比如一个是 public,一个是 internal,则可以书写成下述方式,而不会报错误。
public int ID { get; internal set; }
2.DebuggerNonUserCodeAttribute 标识不属于应用程序用户代码的类型或成员。
如果设计器提供的类型和成员不是由用户专门创建的代码的一部分,则会增加调试过程的复杂性。此特性禁止在调试器窗口中显示这些附属类型和成员,并自动逐句通过而不会进入并单步执行设计器提供的代码。当逐句通过用户代码时,如果调试器遇到此特性,用户将不会看到设计器提供的代码,并且会执行用户提供的下一条代码语句。
[DebuggerNonUserCode]
public void InitializeComponent()
{
if (!this._contentLoaded)
{
this._contentLoaded = true;
Application.LoadComponent(this, new Uri("/ReflectorDemo;component/MainPage.xaml", UriKind.Relative));
this.LayoutRoot = (Grid) base.FindName("LayoutRoot");
}
}
此段代码也是在程序编译后产生。
反编译后将此段代码从源文件中删掉。
3.上图中的private bool _contentLoaded;
此类代码也是在程序编译后产生。
4.internal MediaElement xMedia1
修饰符为internal的变量一般都是(极少数除外)在类对应的Xaml中定义过的变量。因此也应该从源码文件中删掉。