浅谈C# 4.0带来的新特性
2009-10-12 12:12
387 查看
C# 4.0
的主题就是动态编程
(Dynamic Programming)
。虽然
C#
仍然是一种静态语言,但是对象的意义开始变得越来越“动态”。它们的结构和行为无法通过静态类型来捕获,或者至少编译器在编译程序时无法得知对象的结构和行为。
一、
dynamic
关键字
C#
引入了一种新的静态类型”
dynamic
”,当你拥有了一个
dynamic
类型的对象后,你“对它做的事情”只会在运行时进行解析
,
不需要再进行类型转换。
原来要写:
object obj = GetObject();obj.GetType().InvokeMember(“CallSomeFunc”,
…., new object[] { 1 }); //
需要通过反射才能动态调用一个方法
现在只需:
dynamic obj =
GetObject();obj.CallSomeFunc(1);//
直接输入方法名,运行时将会动态调用
二、可选参数
/
命名参数
public
StreamReader OpenTextFile(string path,Encoding encoding = null ,int bufferSize
= 1024);
命名参数必须在最后使用:
OpenTextFile("foo.txt",
Encoding.UTF8, bufferSize: 4096);
顺序不限:
OpenTextFile(bufferSize: 4096, path:
"foo.txt", detectEncoding: false);
三、特定于
COM
的互操作性
在
C#
中在调用
COM
对象如
office
对象时,经常需要写一堆不必要的参数:
object fileName = "Test.docx";object
missing
= System.Reflection.Missing.Value;
doc.SaveAs(ref
fileName,ref missing, ref missing, ref missing,ref missing, ref missing, ref
missing);4.0
中就可以直接写成:
doc.SaveAs("Test.docx");
现在可以直接赋值
:excel.Cells[1, 1].Value =
"Hello";
而不用写
((Excel.Range)excel.Cells[1,
1]).Value2= "Hello";
四、通过委托成员来实现接口
public class Foo : IList<string> {
private List<string> _Collection
implements IList<string>; public Foo() { _Collection = new
List<string>(); }}
在委托实现接口之余,我们也应当可以自由地重写某些方法如下:
public int IList.Add(string value) { if
(!_Collection.Contains(value)) _Collection.Add(value); }
五、安全的
null
延迟赋值操作符
我很想看到一种安全地访问一个值为
null
的对象的属性的表达式,表达式可能形如
Object.Property.Property.Value
比如我要访问
Customer?.FirstName
,但是
Customer
是
null
,此时
Customer?.FirstName
会返回
null
而不是抛出个
NullReferenceException
六、一些
Duck-typing
或
Structural Subtyping
支持
在
.NET
框架中,一部分控件实现了一个叫
ReadOnly
的属性,比如
TextBox, DataGrid, NumericUpDown;
现在我们建一个叫
IReadOnlyRestricable
的接口。
public interface IReadOnlyRestricable { bool ReadOnly { get; set; } }
然后我们要遍历所有的控件,找出有
ReadOnly
属性的控件并把此属性设为
true(
注:这些控件本身没有实现
IReadOnlyRestricable)
,在
ducktyping
下我们可以把控件通过类型转换为
IReadOnlyRestricable
,就像下面代码一样,这样我们就不需要通过反射去定位
ReadOnly
属性了:
foreach (Control c in f.Controls) { IReadOnlyRestricable editable = c as
IReadOnlyRestricable; if (editable != null) editable.ReadOnly = true; }
七、变性
(
协变性和逆变性
)
过去,
IEnumerable<string>
并不是
IEnumerable<object>
,现在它是了。
在
C#
中,下面的类型转换是非法的:
IList<string> strings = new
List<string>();IList<object> objects = strings;
因为你有可能会这样做,而编译器的静态检查无法查出错误:
objects[0] = 5; string s = strings[0];
4.0
中在声明泛型的接口及委托时可以加
in
及
out
关键字,如:
public interface IEnumerable<out T> :
IEnumerable {IEnumerator<T> GetEnumerator();}
out
关键字的意思是说
IEnumerable<T>
中
T
只会被用在输出中,值不会被改变。这样将
IEnumerable<string>
转为
IEnumerable<object>
类型就是安全的。
in
的意思正好相反,是说
IComparer<T>
中的
T
只会被用在输入中,这样就可以将
IComparer<object>
安全的转为
IComparer<string>
类型。前者被称为协变,
后者就是逆变。
的主题就是动态编程
(Dynamic Programming)
。虽然
C#
仍然是一种静态语言,但是对象的意义开始变得越来越“动态”。它们的结构和行为无法通过静态类型来捕获,或者至少编译器在编译程序时无法得知对象的结构和行为。
一、
dynamic
关键字
C#
引入了一种新的静态类型”
dynamic
”,当你拥有了一个
dynamic
类型的对象后,你“对它做的事情”只会在运行时进行解析
,
不需要再进行类型转换。
原来要写:
object obj = GetObject();obj.GetType().InvokeMember(“CallSomeFunc”,
…., new object[] { 1 }); //
需要通过反射才能动态调用一个方法
现在只需:
dynamic obj =
GetObject();obj.CallSomeFunc(1);//
直接输入方法名,运行时将会动态调用
二、可选参数
/
命名参数
public
StreamReader OpenTextFile(string path,Encoding encoding = null ,int bufferSize
= 1024);
命名参数必须在最后使用:
OpenTextFile("foo.txt",
Encoding.UTF8, bufferSize: 4096);
顺序不限:
OpenTextFile(bufferSize: 4096, path:
"foo.txt", detectEncoding: false);
三、特定于
COM
的互操作性
在
C#
中在调用
COM
对象如
office
对象时,经常需要写一堆不必要的参数:
object fileName = "Test.docx";object
missing
= System.Reflection.Missing.Value;
doc.SaveAs(ref
fileName,ref missing, ref missing, ref missing,ref missing, ref missing, ref
missing);4.0
中就可以直接写成:
doc.SaveAs("Test.docx");
现在可以直接赋值
:excel.Cells[1, 1].Value =
"Hello";
而不用写
((Excel.Range)excel.Cells[1,
1]).Value2= "Hello";
四、通过委托成员来实现接口
public class Foo : IList<string> {
private List<string> _Collection
implements IList<string>; public Foo() { _Collection = new
List<string>(); }}
在委托实现接口之余,我们也应当可以自由地重写某些方法如下:
public int IList.Add(string value) { if
(!_Collection.Contains(value)) _Collection.Add(value); }
五、安全的
null
延迟赋值操作符
我很想看到一种安全地访问一个值为
null
的对象的属性的表达式,表达式可能形如
Object.Property.Property.Value
比如我要访问
Customer?.FirstName
,但是
Customer
是
null
,此时
Customer?.FirstName
会返回
null
而不是抛出个
NullReferenceException
六、一些
Duck-typing
或
Structural Subtyping
支持
在
.NET
框架中,一部分控件实现了一个叫
ReadOnly
的属性,比如
TextBox, DataGrid, NumericUpDown;
现在我们建一个叫
IReadOnlyRestricable
的接口。
public interface IReadOnlyRestricable { bool ReadOnly { get; set; } }
然后我们要遍历所有的控件,找出有
ReadOnly
属性的控件并把此属性设为
true(
注:这些控件本身没有实现
IReadOnlyRestricable)
,在
ducktyping
下我们可以把控件通过类型转换为
IReadOnlyRestricable
,就像下面代码一样,这样我们就不需要通过反射去定位
ReadOnly
属性了:
foreach (Control c in f.Controls) { IReadOnlyRestricable editable = c as
IReadOnlyRestricable; if (editable != null) editable.ReadOnly = true; }
七、变性
(
协变性和逆变性
)
过去,
IEnumerable<string>
并不是
IEnumerable<object>
,现在它是了。
在
C#
中,下面的类型转换是非法的:
IList<string> strings = new
List<string>();IList<object> objects = strings;
因为你有可能会这样做,而编译器的静态检查无法查出错误:
objects[0] = 5; string s = strings[0];
4.0
中在声明泛型的接口及委托时可以加
in
及
out
关键字,如:
public interface IEnumerable<out T> :
IEnumerable {IEnumerator<T> GetEnumerator();}
out
关键字的意思是说
IEnumerable<T>
中
T
只会被用在输出中,值不会被改变。这样将
IEnumerable<string>
转为
IEnumerable<object>
类型就是安全的。
in
的意思正好相反,是说
IComparer<T>
中的
T
只会被用在输入中,这样就可以将
IComparer<object>
安全的转为
IComparer<string>
类型。前者被称为协变,
后者就是逆变。
相关文章推荐
- 浅谈Tuple之C#4.0新特性
- Xcode 4.4中LLVM compiler 4.0带来的Objective-C新语法特性
- C# 4.0新特性
- 为什么JVM上没有C#语言?浅谈Type Erasure特性
- NET 4.0 - C# 4.0 新特性之并行运算(Parallel)
- C# 4.0新特性dynamic作用浅析
- C#4.0 新特性 动态类型Dynamic
- 开发者最希望看到的C# 4.0新特性,徐汇区网站设计
- Atitit.c# .net 3.5 4.0 4.5 5.0 6.0各个版本新特性战略规划总结
- Xcode 4.4中LLVM compiler 4.0带来的Objective-C新语法特性
- NET-c# 4.0新特性一览
- VS2010 C# 4.0新特性一览
- c# 4.0新特性
- 谈谈C# 4.0新特性“缺省参数”的实现
- C# 4.0新特性-"协变"与"逆变"以及背后的编程思想
- C# 4.0的一些新特性
- C# 4.0新特性学习资料汇总
- Atitit. C#.net clr 2.0 4.0新特性
- C# 5.0将带来的五大新特性
- C# 4.0新特性