关闭

C#3.5体验

627人阅读 评论(0) 收藏 举报

1.  隐含类型局部变量

var关键字,告诉编译器(对于CLR来说,它是不会知道你是否使用了var, 编译器将其编译为实际类型)自己去推断它的类型。既然让编译器推断类型就必须声明的时候赋值,而且不能是null值。注意,这只能用于局部变量,用于字段是不可以的。

code:

private void TestVarDeclare()
        {
            var age = 26;
            var userName = "Archer";
            var list = new[] { "Archer", "LeeWei", "Alona" };

            foreach (var user in list)
            {
                Console.WriteLine(user);
            }
           // Console.Read();
        }

IL:

  .locals init ([0] int32 age,
           [1] string userName,
           [2] string[] list,
           [3] string user,
           [4] string[] CS$0$0000,
           [5] string[] CS$6$0001,
           [6] int32 CS$7$0002,
           [7] bool CS$4$0003)

从IL可以看出,编译器已经将其编译为合适的数据类型。

 

2. 匿名类型

匿名类型允许开发人员定义行内类型,无须显式定义类型。常和var配合使用,var用于声明匿名类型。

private void AnonymityClassTest()
        {
            var data = new {username = "Archer", age = 20};
            Console.WriteLine(data.username);
            Console.WriteLine(data.age);
           
        }

IL:

.method private hidebysig instance void  AnonymityClassTest() cil managed

{

  // Code size       39 (0x27)

  .maxstack  3

  .locals init ([0] class '<>f__AnonymousType0`2'<string,int32> data)

  IL_0000:  nop

  IL_0001:  ldstr      "Archer"

  IL_0006:  ldc.i4.s   20

  IL_0008:  newobj     instance void class '<>f__AnonymousType0`2'<string,int32>::.ctor(!0,

                                                                                        !1)

  IL_000d:  stloc.0

  IL_000e:  ldloc.0

  IL_000f:  callvirt   instance !0 class '<>f__AnonymousType0`2'<string,int32>::get_username()

  IL_0014:  call       void [mscorlib]System.Console::WriteLine(string)

  IL_0019:  nop

  IL_001a:  ldloc.0

  IL_001b:  callvirt   instance !1 class '<>f__AnonymousType0`2'<string,int32>::get_age()

  IL_0020:  call       void [mscorlib]System.Console::WriteLine(int32)

  IL_0025:  nop

  IL_0026:  ret

} // end of method Program::AnonymityClassTest

 

另外,我们可以在IS Disassembler中看见这个<>f__AnonymousType0`2'是作为一个单独的类存在的

 

3. 扩展方法

扩展方法的定义,需要注意三个部分:1、静态类(私有公共都可以);2、静态方法(私有公共都可以);3、第一个函数参数前带 this(必须是第一参数前)

,如果扩展方法名和原有方法名发生冲突,那么扩展方法将失效。

Code:

 public static class ExtensionMethodClass
    {
        public static string AddString(this string str, string input)
        {
            return str + input;
        }

    }

 private void ExtensionMethod()
        {
            string testStr = "Archer";
            string result = testStr.AddString("Chen");
            Console.WriteLine(result);
        }
IL:

扩展方法实际是编译器调用某个类的某个方法的时候,先去这个类找,如果有这个方法,则就调用;如果找不到,根据引用的命名空间,再去找扩展方法(静态类的静态方法)。找到,就使用,找不到当然就编译错误了。

由此看来扩展方法和隐藏变量一样,也是编译器干的苦活, 而跟CLR无关

 


 4. 自动属性
这个没有什么意思, 纯粹是个偷懒的方法。编译器自动为你生成get、set操作以及字段,并且你不能使用私有字段(由编译器自动生成)也不能自定义get、set操作,不过你可以分别定义get和set的访问级别。

Code:
public class Person

    {

        public string username { get; protected set; }

        public int age { get; set; }

       

        public Person()

        {

            this.username = "zhuye";           

        }

}

IL:
会发现中间语言和自己写区别不大, 只是自动添加了<username>k__BackingField, 和<age>k__BackingField两个私有字段。

 

5. 对象初始化器

编译器会自动为你做setter操作,使得原本几行的属性赋值操作能在一行中完成。这里需要注意:
1. 允许只给一部分属性赋值,包括internal访问级别
2. 可以结合构造函数一起使用,并且构造函数初始化先于对象初始化器执行

Code:

Person p = new Person() {username = "Archer", age=26};
Console.WriteLine(p.ToString());

IL:

IL_0001:  newobj     instance void CSharp3._Test.Person::.ctor()
  IL_0006:  stloc.1
  IL_0007:  ldloc.1
  IL_0008:  ldstr      "archer"
  IL_000d:  callvirt   instance void CSharp3._Test.Person::set_username(string)
  IL_0012:  nop
  IL_0013:  ldloc.1
  IL_0014:  ldc.i4.s   26
  IL_0016:  callvirt   instance void CSharp3._Test.Person::set_age(int32)
从IL中可以看见, 编译器现调用构造函数构造对象,然后调用对象的属性赋值。

注Person p = new Person() {username = "Archer", age=26};和new person {username = "Archer", age=26}, 参数为空,和不指定参数是有区别的

 

6.集合初始化器


和对象初始化器类同

 

7. Lambda表达式

 其实和2.0中的匿名方法差不多,都是用于产生内联方法,只不过Lambda表达式的语法更为简洁。语法如下:

       (参数列表) => 表达式或者语句块

其中:

参数个数:可以有多个参数,一个参数,或者无参数。

表达式或者语句块:这部分就是我们平常写函数的实现部分(函数体)。

Code:
var list = new [] { "aa", "bb", "ac" };
var result = Array.FindAll(list, s => (s.IndexOf("a") > -1));
foreach (var v in result)
{
Console.WriteLine(v);
}

IL:

.locals init ([0] bool CS$1$0000)
  IL_0000:  ldarg.0
  IL_0001:  ldstr      "a"
  IL_0006:  callvirt   instance int32 [mscorlib]System.String::IndexOf(string)
  IL_000b:  ldc.i4.m1
  IL_000c:  cgt
  IL_000e:  stloc.0
  IL_000f:  br.s       IL_0011
  IL_0011:  ldloc.0
  IL_0012:  ret

 


8. 查询句法

查询句法是使用标准的LINQ查询运算符来表达查询时一个方便的声明式简化写法。该句法能在代码里表达查询时增进可读性和简洁性,读起来容易,也容易让人写对。Visual Studio 对查询句法提供了完整的智能感应和编译时检查支持。编译器在底层把查询句法的表达式翻译成明确的方法调用代码,代码通过新的扩展方法和Lambda表达式语言特性来实现。
 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:19166次
    • 积分:332
    • 等级:
    • 排名:千里之外
    • 原创:9篇
    • 转载:13篇
    • 译文:0篇
    • 评论:1条
    文章存档