1. 概述
本章介绍 值类型的装箱拆箱、类型转换 以及 C#4.0新推出的 dynamic 关键字。
2. 主要内容
2.1 装箱和拆箱
2.2 类型转换
有四种方式可以实现类型转换:
① 隐式转换:编译器允许的,类型安全的转换。无需特殊的标记符号,编译器直接转换。
② 显式转换:无法隐式转换,可能会丢失精度的情况,需要用类型符号来强制转换。
③ 自定义转换
class Money { public Money(decimal amount) { Amount = amount; } public decimal Amount { get; set; } public static implicit operator decimal(Money money) { return money.Amount; } public static explicit operator int(Money money) { return (int)money.Amount; } } Money money = new Money(42.23M); decimal amount = money; int truncatedAmount = (int)money;
④ 使用辅助类转换(System.BitConvertor, System.Convert, Parse, TryParse)
int value = Convert.ToInt32("42"); value = int.Parse("42"); bool success = int.TryParse("42", out value);
* is 和 as 关键字,可以验证转换是否可行。如果仅判断不做实际转换,用is,否则用as。两者都可用于Nullable。
void OpenConnection(DbConnection con) { if (con is SqlConnection) ... } void LogStream(Stream stream) { MemoryStream memoryStream = stream as MemoryStream; if (memoryStream != null) ... }
2.3 使用动态类型(dynamic types)
使用dynamic的地方,编译器不会做类型检测。使用的地方一般包括:
① 与外部资源交互时。比如 COM Interop、Iron-Pathon、JSON、DOM。
② 在C#中使用反射时。
static void DisplayInExcel(IEnumerable<dynamic> entities) { var excelApp = new Excel.Application(); excelApp.Visible = true; excelApp.Workbooks.Add(); dynamic worksheet = excelApp.ActiveSheet; worksheet.Cells[1, "A"] = "Header A"; worksheet.Cells[1, "B"] = "Header B"; var row = 1; foreach(var entity in entities) { row++; worksheet.Cells[row, "A"] = entity.ColumnA; worksheet.Cells[row, "B"] = entity.ColumnB; } worksheet.Columns[1].AutoFit(); worksheet.Columns[2].AutoFit(); } var entities = new List<dynamic> { new { ColumnA = 1, ColumnB = "Foo"}, new { ColumnA = 2, ColumnB = "Bar"} };
DisplayInExcel(entities);
DynamicObject 和 ExpandoObject
public class SampleObject : DynamicObject { public override bool TryGetMember(GetMemberBinder binder, out object result) { result = binder.Name; return true; } } dynamic obj = new SampleObject(); Console.WriteLine(obj.SomeProperty); //displays 'SomeProperty'
//ExpandoObject
public ActionResult Index() { ViewBag.MyDynamicValue = "This property is not statically typed"; return View(); }
3. 总结
① 当一个值类型被当做引用类型使用时,就会发生装箱。
② 需要类型转换时,可以使用隐式和显式转换。并且可以定义自己的隐式和显式转换。
③ dynamic 关键字可以绕过C#的类型检测,可以与其他语言更好的交互。