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

重新认识C#

2009-05-29 13:42 197 查看
c#4.0白皮书:http://www.cnblogs.com/AndersLiu/archive/2008/11/03/1325148.html

白皮书资料不包括1,2,3,4特性,猜想或许是C#5.0的特性吧 :-)

1. 通过委托成员来实现接口

public class Foo : IList
{
  private List _Collection { get; set; } implements IList;
  public Foo()
  {
  _Collection = new List();
  }
  public int IList.Add(string value)
  {
  if (!_Collection.Contains(value))
  _Collection.Add(value);
  }
}
用聚合代替继承实现接口,提供更彻底的支持!

2. 匿名返回类型

public var GetProductInfos()
{
  var productInfos =
  from p in products
  select new { p.ProductName, p.Category, Price = p.UnitPrice };
  return productInfos;
}
在我看来,真正的问题是匿名类型如何在WCF中传输。

3. 鸭子类型

如果一个类中的某一个方法/属性的签名和某个接口一样,并且这个类没有实现此接口,那么这个类就将隐式地实现这个接口。只有这个类实现了接口规定的所有方法/属性的时候才被认为隐式地实现了此接口。

可以省略小接口的定义,可以减少运行期反射访问成员属性和方法。

4. null对象属性为null

int? orderNumber = customer?.Order?.OrderNumber;

再也不用这样写了:

int? orderNumber;

if (customer != null && customer.Order != null)

orderNumber = customer.Order.OrderNumber;

else

orderNumber=null;

5. 动态类型变量

dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);

声明为dynamic类型的变量完全忽略静态类型检查,所有操作转换为反射调用。

dynamic的实现是基于IDynamicObject接口和DynamicObject抽象类。而动态方法、属性的调用都被转为了GetMember、Invoke等方法的调用。可以不去关心对象是来源于COM, IronPython, HTML DOM或者反射,只要知道有什么方法可以调用就可以了。

动态类型与静态类型编程序有什么区别?静态类型检查使排错更容易,编译器会辅助纠错。

但动态类型可以提高编程效率,人脑可控的代码片,不需要电脑给我任何警告和提示。

C#开始融合这两种编码技术。

比var变量更彻底,var变量仅支持动态声明,初始化后即确定类型。

public abstract class DynamicObject : IDynamicObject
{
public virtual object GetMember(GetMemberBinder info);
public virtual object SetMember(SetMemberBinder info, object value);
public virtual object DeleteMember(DeleteMemberBinder info); public virtual object UnaryOperation(UnaryOperationBinder info);
public virtual object BinaryOperation(BinaryOperationBinder info, object arg);
public virtual object Convert(ConvertBinder info); public virtual object Invoke(InvokeBinder info, object[] args);
public virtual object InvokeMember(InvokeMemberBinder info, object[] args);
public virtual object CreateInstance(CreateInstanceBinder info, object[] args); public virtual object GetIndex(GetIndexBinder info, object[] indices);
public virtual object SetIndex(SetIndexBinder info, object[] indices, object value);
public virtual object DeleteIndex(DeleteIndexBinder info, object[] indices); public MetaObject IDynamicObject.GetMetaObject(); }

6. 命名参数和可选参数

函数声明时设置形参默认值,调用时可在实参列表指定参数名。

7. 协变和逆变

IList<string> strings = new List<string>();
IEnumerable<object> objects = strings;

in,out标识提供对泛型对象赋值操作更多的支持。

在声明generic的Interface及Delegate时可以加in及out关键字

System.Collections.Generic.IEnumerable<out T>
System.Collections.Generic.IEnumerator<out T>
System.Linq.IQueryable<out T>
System.Collections.Generic.IComparer<in T>
System.Collections.Generic.IEqualityComparer<in T>
System.IComparable<in T>

System.Func<in T, …, out R>
System.Action<in T, …>
System.Predicate<in T>
System.Comparison<in T>
System.EventHandler<in T>

对于类型系统来说,接口实现和类型继承本质上是一致的。契约是弱类型,签署这份契约的是强类型。

强类型和弱类型指的是两个具有直接或者间接继承关系的两个类。如果一个类是另一个类的直接或者间接基类,那么它为弱类型,直接或者间接子类为强类型。Bar继承自Foo。Foo是弱类型,而Bar则是强类型。

如果类型TBar是基于强类型Bar的泛型(比如类型参数为Bar的泛型类型,或者是参数/返回值类型为Bar的委托),而类型TFoo是基于弱类型Foo的泛型,协变就是将TBar类型的实例赋值给TFoo类型的变量,而逆变则是将TFoo类型的实例赋值给TBar类型的变量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: