.NET - 如何使用“as”进行显式强制转换(内部)与 (someType)someobject 不同,为什么?

发布于 2024-10-18 08:36:32 字数 391 浏览 0 评论 0原文

据我所知,当您使用这样的显式强制转换时:

(someType)someobject

如果 someobject 不是真正的 someType,您可能会收到无效的强制转换异常。

我也明白,当您像这样使用 as 进行转换时:

myObject = someObject as someType

如果 someObject 不是',则 myObject 只是呈现 null确实是someType

这些评估有何不同,为什么?

I understand that when you use an explicit cast like this:

(someType)someobject

you can get an invalid cast exception if someobject is not really someType.

As well I understand that when you cast with as like this:

myObject = someObject as someType

myObject is just rendered null if someObject isn't really someType.

How are these evaluated differently and why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月亮是我掰弯的 2024-10-25 08:36:32

John Skeet 有一个 C# 常见问题解答,其中解释了两个运算符之间的差异。请参阅“使用强制转换语法和 as 运算符之间有什么区别?”段落。

引用 :

使用 as 运算符与 a
在 C# 中通过三种重要方式进行强制转换:

  1. 当您尝试转换的变量为
    不是所请求的类型或不属于其类型
    继承链,而不是抛出
    一个例外。
  2. 它只能应用于引用类型变量转换为
    参考类型。
  3. 使用 as 不会执行用户定义的转换,例如
    隐式或显式转换
    运算符,该转换语法将
    做。

实际上完全有两个
IL 中定义的不同操作
处理这两个关键字(
castclassisinst 指令)-
这不仅仅是“语法糖”
由 C# 编写,以实现不同的效果
行为。 as 运算符似乎
在 v1.0 和 v1.1 中稍微快一些
Microsoft 的 CLR 与强制转换相比
(即使在没有的情况下
无效的强制转换会严重影响
铸件性能较低,因为
例外)。

John Skeet has a C# faq where he explains the differences between the two operators. See paragraph 'What's the difference between using cast syntax and the as operator?'.

Quote :

Using the as operator differs from a
cast in C# in three important ways:

  1. It returns null when the variable you are trying to convert is
    not of the requested type or in its
    inheritance chain, instead of throwing
    an exception.
  2. It can only be applied to reference type variables converting to
    reference types.
  3. Using as will not perform user-defined conversions, such as
    implicit or explicit conversion
    operators, which casting syntax will
    do.

There are in fact two completely
different operations defined in IL
that handle these two keywords (the
castclass and isinst instructions) -
it's not just "syntactic sugar"
written by C# to get this different
behavior. The as operator appears to
be slightly faster in v1.0 and v1.1 of
Microsoft's CLR compared to casting
(even in cases where there are no
invalid casts which would severely
lower casting's performance due to
exceptions).

月依秋水 2024-10-25 08:36:32

几年过去了......但几分钟前我遇到了一个我认为值得注意的实际例子 - 两者之间的区别:

检查一下:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(GenericCaster<string>(12345));
        Console.WriteLine(GenericCaster<object>(new { a = 100, b = "string" }) ?? "null");
        Console.WriteLine(GenericCaster<double>(20.4));

        //prints:
        //12345
        //null
        //20.4

        Console.WriteLine(GenericCaster2<string>(12345));
        Console.WriteLine(GenericCaster2<object>(new { a = 100, b = "string" }) ?? "null");

        //will not compile -> 20.4 does not comply due to the type constraint "T : class"
        //Console.WriteLine(GenericCaster2<double>(20.4));

        /*
         * Bottom line: GenericCaster2 will not work with struct types. GenericCaster will.
         */
    }

    static T GenericCaster<T>(object value, T defaultValue = default(T))
    {
        T castedValue;
        try
        {
            castedValue = (T) Convert.ChangeType(value, typeof(T));
        }
        catch (Exception)
        {
            castedValue = defaultValue;
        }

        return castedValue;
    }

    static T GenericCaster2<T>(object value, T defaultValue = default(T)) where T : class
    {
        T castedValue;
        try
        {
            castedValue = Convert.ChangeType(value, typeof(T)) as T;
        }
        catch (Exception)
        {
            castedValue = defaultValue;
        }

        return castedValue;
    }
}

底线: GenericCaster2 不适用于结构类型。 GenericCaster 会的。

Years have passed... but minutes ago I came across a practical example I think is worth noting - of the difference between the two:

Check this out:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(GenericCaster<string>(12345));
        Console.WriteLine(GenericCaster<object>(new { a = 100, b = "string" }) ?? "null");
        Console.WriteLine(GenericCaster<double>(20.4));

        //prints:
        //12345
        //null
        //20.4

        Console.WriteLine(GenericCaster2<string>(12345));
        Console.WriteLine(GenericCaster2<object>(new { a = 100, b = "string" }) ?? "null");

        //will not compile -> 20.4 does not comply due to the type constraint "T : class"
        //Console.WriteLine(GenericCaster2<double>(20.4));

        /*
         * Bottom line: GenericCaster2 will not work with struct types. GenericCaster will.
         */
    }

    static T GenericCaster<T>(object value, T defaultValue = default(T))
    {
        T castedValue;
        try
        {
            castedValue = (T) Convert.ChangeType(value, typeof(T));
        }
        catch (Exception)
        {
            castedValue = defaultValue;
        }

        return castedValue;
    }

    static T GenericCaster2<T>(object value, T defaultValue = default(T)) where T : class
    {
        T castedValue;
        try
        {
            castedValue = Convert.ChangeType(value, typeof(T)) as T;
        }
        catch (Exception)
        {
            castedValue = defaultValue;
        }

        return castedValue;
    }
}

Bottom line: GenericCaster2 will not work with struct types. GenericCaster will.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文