随便看看两种类型转换方式对应的的IL代码

.
例行吐槽:别人整天大数据云计算架构算法啥的,为什么我还在看这些如此不高端而且没人用的东西呢?


一种是前面写个括号的类型转换(俗称强转),还有一种是加个as的类型转换。

首先写个不知道有啥用的类。

public class CastTest
{
    public void DoSth()
    {
        ArrayList list = new ArrayList();
        this.doSth(this.forceCast(list));
        this.doSth(this.asCast(list));
    }

    private IList forceCast(object list)
    {
        if (list is IList)
        {
            return (IList)list;
        }
        return null;
    }

    private IList asCast(object list)
    {
        if (list is IList)
        {
            return list as IList;
        }
        return null;
    }

    private void doSth(IList list)
    {
        if (list != null)
        {
            Console.WriteLine(list.Count);
        }
    }
}

编译完之后用反编译工具打开。

先看第一个方法:

csharp code 1

对应的IL:

il code 1

可以看到调用了 castclass 方法进行了转换。

然后是第二个方法:

csharp code 2

对应的IL

il code 2

这里觉得很奇怪,因为只是判断了下是否为指定的类型,就和上面 if 那里的是一模一样的,然后紧接着就 return 了。

于是去看了下 isinst 的文档。

OpCodes.Isinst Field

Tests whether an object reference (type O) is an instance of a particular class.

Description

Tests if an object reference is an instance of class, returning either a null reference or an instance of that class or interface. Class is a metadata token indicating the desired class. If the class of the object on the top of the stack implements class (if class is an interface) or is a derived class of class (if class is a regular class) then it is cast to type class and the result is pushed on the stack, exactly as though Castclass had been called. Otherwise, a null reference is pushed on the stack. If the object reference itself is a null reference, then isinst likewise returns a null reference.

注意到其中那句 “exactly as though Castclass had been called. “

也就是说 list is IListlist as IList 这两句执行的东西其实是一模一样的。

另外再看看 castclass 的文档。

OpCodes.Castclass Field

Attempts to cast an object passed by reference to the specified class.

Description

Casts an object to a new object of type class.

The stack transitional behavior, in sequential order, is:

  1. An object reference is pushed onto the stack.
  2. The object reference is popped from the stack; the referenced object is cast as the specified class.
  3. If successful, a new object reference is pushed onto the stack.

The castclass instruction attempts to cast the object reference (type O) atop the stack to a specified class. The new class is specified by a metadata token indicating the desired class. If the class of the object on the top of the stack does not implement the new class (assuming the new class is an interface) and is not a derived class of the new class then an InvalidCastException is thrown. If the object reference is a null reference, castclass succeeds and returns the new object as a null reference.

有两个地方:

首先是 “If successful, a new object reference is pushed onto the stack.“,是不是就是说会重新创建一个实例。


为此我打算测试一下。

写段不知道有啥用的代码先:

public void Cast()
{
    BClass b = new BClass(3);
    AClass a1 = (AClass)b;
    AClass a2 = b as AClass;
}

public class AClass
{
    public AClass()
    {
        Console.WriteLine("new Instance of AClass created at {0:hh:MM:ss.fff}", DateTime.Now);
    }
}

public class BClass : AClass
{
    public BClass(int i) { }
}

然后发现实例化 BClass 的时候 AClass 的构造函数也被触发了,虽说这是基础中的基础,但我还真不知道。。。

总之结果是,不会创建新的实例。


还有就是 “then an InvalidCastException is thrown.” 这句,如果无法转换就会抛出异常,而在 isinst 里面并没有异常抛出,而是 “Otherwise, a null reference is pushed on the stack.” 直接返回 null 了。

这真是懒人的福音啊。。。


如果很不幸真有人要转载这种文章,就说是你写的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值