第七章 管理类型(In .net4.5) 之 使用类型

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);

    * isas 关键字,可以验证转换是否可行。如果仅判断不做实际转换,用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);

    DynamicObjectExpandoObject

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#的类型检测,可以与其他语言更好的交互。