C#特性编程(1)

  在英文资料中,类的属性被称为"Property",而特性被称为"Attribute",字面上容易混淆,不过它们有着很大的差异。属性是类定义中用于封装成员访问的手段,使对象的数据成员访问既简单又安全。类成员的特性被称为元数据中的注释,可以允许开发者添加更多自己的信息和注解,并通过反射技术在程序运行时获取。

面试例题11:如何通过特性使程序代码符合CLS?

考点:理解CLS的含义以及[CLSCompliant]特性。

出现频率:★

解答

  通过在程序集中声明[assembly: CLSCompliant(true)]特性即可保证整个程序集代码遵守CLS,否则编译时将报错。如果程序集代码中某些元素(如属性)需要逃避符合是否 CLS的检查,可添加[property: CLSCompliant(false)]特性注释。在目录下新建一个程序文件,并命名为AttributeTest.cs,编写代码如代码7.15所示。

代码7.15 强制符合CLS特性:AttributeTest.cs

+展开
-C#
using System;

//声明程序集的CLSCompliant特性
[assembly: CLSCompliant(true)]
class AttributeTest
{
static void Main(string[] args)
{
Person p = new Person();
/*由于_age不符合CLS,所以编译无法通过
*p._age = 25;
*Console.WriteLine(p._age);*/

p.age = 25;
Console.WriteLine(p.age);
}
}
public class Person
{
//_name字段不是公共成员,所以不会被检查是否符合CLS
string _name = "C#中定义的名称";
//由于_age不符合CLS,所以编译无法通过
//public int _age = 20;
public int age = 20;
//以下代码后声明_Name属性不符合CLR,可以通过编译
[property: CLSCompliant(false)]
public string _Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
//以下代码后声明somewords方法不符合CLR,可以通过编译
[method: CLSCompliant(false)]
public void somewords()
{
Console.WriteLine("调用了somewords方法");
}
public void Somewords()
{
Console.WriteLine("调用了Somewords方法");
}
}

  在目录下新建一个程序文件,并命名为VBTest.vb,编写代码如代码7.16所示。

代码7.16 VB.NET程序:VBTest.vb

+展开
-VBScript
Imports System


Public Module VBTest
Public Sub Main()
'创建Person类型的对象p
Dim p As New Person()
'分别输出p对象的_Name属性值和age字段值
'由于VB.net支持下划线开头的变量,所以可正常访问该属性
Console.WriteLine("p的原始姓名为【{0}】", p._Name)
Console.WriteLine("p的原始年龄为【{0}】", p.age)
'接收用户输入的2组值,并将第2个值转换为int类型
'分别赋值给p的_Name属性和age字段,最后输出_Name属性和age字段的新值
Console.Write(vbCrLf + "请修改p的姓名:")
p._Name = Console.ReadLine
Console.WriteLine("fp的新姓名为【{0}】", p._Name)
Console.Write(vbCrLf + "请修改p的年龄:")
p.age = CInt(Console.ReadLine)
Console.WriteLine("p的新年龄为【{0}】", p.age)
'以下代码将编译报错,因为VB.net大小写不敏感
'VB.net将Somewords方法和somewords方法视为相同方法
'p.Somewords()
'p.somewords()
End Sub
End Module

  在命令行下编译AttributeTest.cs为p.dll程序集,然后编译VBTest.cs并引用p.dll程序集,执行VBTest.exe程序,运行结果如图7.17所示。

VB.NET程序运行结果

图7.17 VB.NET程序运行结果



  用VB.NET Visual Basic .NET编写的VBTest程序集成功地访问了C#所编写的程序集。在AttributeTest.cs代码中,_Name属性逃避了是符合CLS的检查,但VB.NET仍然能正常访问。这是因为标识符虽然以下划线开头不符合CLS,但符合VB.NET的语法规范。而somewords()方法虽然逃避了符合CLS检查,但是由于不符合VB.NET的规范,而无法被访问。

  本例涉及了C#和VB.NET的合作,显示了CLS的巨大作用。灵活使用特性可以使程序的各个部分能根据需要选择是否符合CLS。

解析

  CLS即公共语言规范,它保证整个应用程序可以无缝跨越.NET的各种语言。例如C#中的多个相同字母组合的标识符可以通过字母大小写不同而区分,但是VB.NET视为非法,C#的这种做法被称为没有遵守CLS。在程序集中声明[CLSCompliant]特性即可保证编译时检查程序集代码遵守 CLS,从而有利于其他.NET语言的调用。[CLSCompliant]特性的编写方法如以下代码所示:

+展开
-C#
//可声明整个程序集必须遵守CLS
[assembly: CLSCompliant(true)]
//可声明被注释的属性可以不遵守CLS,即可正常通过编译
[property: CLSCompliant(false)]
//可声明被注释的方法可以不遵守CLS,即可正常通过编译
[method: CLSCompliant(false)]

  以上代码,CLSCompliant的参数为bool类型值,表示所注释项是否遵守CLS。

面试例题12:如何使用特性在编译时给出警告?

考点:理解[Obsolete]特性,学习[Obsolete]特性的使用方法。

出现频率:★★

解答

  在类或成员前注释[Obsolete]特性,一旦主程序中使用了该类或成员,可以在编译时给出警告。在目录下新建一个程序文件,并命名为ObsoletetTest.cs,编写代码如代码7.17所示。

代码7.17 [Obsolete]特性的使用:ObsoletetTest.cs

+展开
-C#
using System;

//声明程序集的CLSCompliant特性
[assembly: CLSCompliant(true)]
class ObsoletetTest
{
static void Main(string[] args)
{
//创建Person类的对象p
Person p = new Person();
//赋值给p的_Name属性,并将其输出
p._Name = "比尔";
Console.WriteLine(p._Name);
//调用Person类的Somewords静态方法
Person.Somewords();
}
}
public class Person
{
string _name;
//以下代码后声明_Name属性不符合CLR,可以通过编译
//如果访问_Name属性编译时将出现警告
[property: CLSCompliant(false),Obsolete("读写_name字段请使用Name属性")]
//旧属性,可以读写_name字段,因为不符合CLS,建议不要使用
public string _Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
//新属性,也可以读写_name字段
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
//如果访问_Name属性编译时将出现警告
[Obsolete("该方法没有什么意义,请不要使用")]
internal static void Somewords()
{
Console.WriteLine("调用了Somewords方法");
}
}

  在命令行下编译ObsoletetTest.cs,执行ObsoletetTest程序,运行结果如图7.18所示。

[Obsolete特性的使用

图7.18 [Obsolete]特性的使用

来源:http://www.51cto.com

加支付宝好友偷能量挖...


评论(0)网络
阅读(147)喜欢(0)Asp.Net/C#/WCF