您的位置:首页 > 编程语言 > C#

C# in depth (第八章 用智能的编译器来防错)

2015-08-21 18:39 555 查看
8.1 自动实现的属性

公开可见的静态成员通常应该是线程安全的,编译器在这方面帮不上什么忙,得自己去实现

public class InstanceCountingPerson
{
public string Name { get; private set; }
public int Age { get; private set; }

private static int InstanceCounter { get; set; }
private static readonly object counterLock = new object();

public InstanceCountingPerson(string name, int age)
{
Name = name;
Age = age;

lock (counterLock)
{
InstanceCounter++;
}
}
}


作者见过的使用静态自动属性的唯一情况是,取值方法是公共的,赋值方法是私有的,并且赋值方法只能在类型初始化程序中使用。

(以下代码无法通过编译)

public struct Foo
{

public int Value { get; private set; }

public Foo(int value)
{
this.Value = value;
}
}


只有加上this 才可以

public struct Foo
{

public int Value { get; private set; }

public Foo(int value) :this()
{
this.Value = value;
}
}


8.2 隐式类型的局部变量

8.2.1 用var声明局部变量

8.2.2 隐式类型的限制

被声明的变量是一个局部变量,而不是静态字段和实例字段。

变量在声明的同时被初始化;

初始化表达式不是方法组,也不是匿名函数。

初始化表达式不是null

语句中只声明了一个变量。

你希望变量拥有的类型是初始化表达式的编译时类型

初始化表达式不包含正在声明的变量。

8.2.3 隐式类型的优缺点

8.2.4 建议

8.3 简化的初始化

8.3.1定义示例类型

public class Person
{
public int Age { get; set; }
public string Name { get; set; }

List<Person> friends = new List<Person>();
public List<Person> Friends
{
get { return friends; }
}

Location home = new Location();
public Location Home
{
get { return home; }
}

public Person()
{
}

public Person(string name)
{
Name = name;
}
}

public class Location
{
public string Country { get; set; }
public string Town { get; set; }
}


8.3.2 设置简单属性

Person tom3 =new Person(){ Name ="Tom", Age=9};
Person tom4 =new Person{ Name ="Tom", Age=9};
Person tom5 =new Person("Tom") {Age=9};


C#3.0可以用一个表达式来设置对象的所有属性

Person[] family = new Person[]
{
new Person{Name ="Holly", Age=36},
new Person{Name ="Jon", Age=36},
new Person{Name ="Tom", Age=9},
new Person{Name ="William", Age=6},
new Person{Name ="Robin", Age=6}
}


8.3.3 为嵌入对象设置属性

Person tom = new Person("Tom")
{
Age =9;
Home ={Country ="UK", Town ="Reading"}
}


8.3.4 集合初始化程序

1.使用集合初始化程序来创建新集合。

var names = new List<string>{"Holly","Jon","Tom","Robin","Williaam"};


2.在其他对象初始化程序中填充集合

class ObjectInitializer
{
static void Main()
{
Person tom = new Person
{
Name = "Tom",
Age = 9,
Home = { Town = "Reading", Country = "UK" },
Friends =
{
new Person { Name = "Alberto" },
new Person("Max"),
new Person { Name = "Zak", Age = 7 },
new Person("Ben"),
new Person("Alice")
{
Age = 9,
Home = { Town = "Twyford", Country="UK" }
}
}
};
}
}


8.3.5 初始化特性的应用

8.4 隐式类型的数组

例如,以下语句编译起来没有任何问题

string[] names = {"Holly", "Jon", "Tom", "Robin", "William" };


但这种写法不适用于参数:

MyMethod(("Holly","Jon","Tom","Robin","William");
这种写法无法通过编译。


需要写成这样:

MyMethod(new[]("Holly","Jon","Tom","Robin","William")));


8.5 匿名类型

如果分开来看,隐式类型,对象和组合初始化程序以及隐士数组类型均有或大或小的用处。然而它们也可以组合起来使用,从而服务于一个更高的目标,也就是本章最后要讲述的一个特性:匿名类型。而匿名类型又服务员一个更高的目标:LINQ

8.5.1 第一次邂逅匿名类型

class FirstAnonymousType
{
static void Main()
{
var tom = new { Name = "Tom", Age = 9 };
var holly = new { Name = "Holly", Age = 37 };
var jon = new { Name = "Jon", Age = 36 };

Console.WriteLine("{0} is {1} years old", jon.Name, jon.Age);
}
}


class AnonymousTypeInArray
{
static void Main()
{
var family = new[]
{
new { Name = "Holly", Age = 37 },
new { Name = "Jon", Age = 36 },
new { Name = "Tom", Age = 9 },
new { Name = "Robin", Age = 6 },
new { Name = "William", Age = 6 }
};

int totalAge = 0;
foreach (var person in family)
{
totalAge += person.Age;
}
Console.WriteLine("Total age: {0}", totalAge);
}
}


8.5.2 匿名类型的成员

匿名类型包含以下成员:

一个获取所有初始值的构造函数。参数的顺序和它们在匿名对象初始化程序中的顺序一样,名称和类型也一样;

公有的只读属性

属性的私有只读字段

重写的Equals,GetHashCode和ToString。

8.5.3 投影初始化程序

class Projection
{
static void Main()
{
List<Person> family = new List<Person>
{
new Person { Name="Holly", Age=37 },
new Person { Name="Jon", Age=36 },
new Person { Name="Tom", Age=9 },
new Person { Name="Robin", Age=6 },
new Person { Name="William", Age=6 }
};

var converted = family.ConvertAll(delegate(Person person)
{ return new { person.Name, IsAdult = (person.Age >= 18) }; }
);

foreach (var person in converted)
{
Console.WriteLine("{0} is an adult? {1}",
person.Name, person.IsAdult);
}
}
}


8.5.4 重点何在

避免过度的数据积累

匿名类型

为一种进行裁减的数据封装 避免手动编写重复的代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: