【问题标题】:Difference between as operator and casting (generics involved)as operator 和 cast 之间的区别(涉及泛型)
【发布时间】:2011-01-31 14:20:13
【问题描述】:

最近我遇到了与演员表相关的奇怪问题。我看到的每一个讨论/帖子都倾向于围绕使用铸造,当一个人确定被铸造的对象加上几个细节时。但是我还没有找到下面代码背后的原因:

class Program
{
    static void Main(string[] args)
    {
        var h = new SomeCommandHandler();
        var c = h as ICommandHandler<ICommand>; //this works as expected
        //var c = (ICommandHandler<ICommand>)h; //this throws - why?
    }

    interface ICommand { }
    class SomeCommand : ICommand { }

    interface ICommandHandler<I> where I : ICommand { }
    class SomeCommandHandler : ICommandHandler<SomeCommand> { }
}

那么为什么第二次调用会抛出异常呢?我不知道的 cast 和 as 运算符有什么区别?

编辑: 它会在上面的注释行中抛出 “未处理的异常:System.InvalidCastException:无法将 'SomeCommandHandler' 类型的对象转换为类型 'ICommandHandler`1[ConsoleApplication1.Program+ICommand]'”

【问题讨论】:

  • @thecoop - 冒险猜测它是一个 InvalidCastException...

标签: c# generics casting


【解决方案1】:

嗯,这就是全部不同之处。 as 运算符返回 null 如果对象无法转换为该类型,并且仅转换会产生异常。

【讨论】:

  • Errr 不确定我是如何忽略这一点的。我很确定示例中的“as”返回了非空值...
【解决方案2】:

其他人已经解释了直接转换抛出异常和as在转换失败时返回null之间的区别。为了能够进行这样的转换成功,您需要使通用接口逆变:

interface ICommandHandler<out I> where I : ICommand { }

但是,这可能是不可能的,这取决于界面的实际外观(为简洁起见,我假设您展示的是精简版)。如果您的接口包含接受I 类型参数的方法,这将不起作用; I 类型只能出现在 get 操作中:

interface ICommandHandler<out I> where I : ICommand 
{
    void SetCommand(I n); // this would not be allowed...
    I GetCommand();       // ...but this would.
}

【讨论】:

  • 猜猜看。我需要它作为参数 (void Execute(SomeCommand cmd)) 所以,正如你所说,协方差对我没有帮助。无论如何感谢您的帮助!
【解决方案3】:

它会抛出一个异常,因为 h 的类型是 SomeCommandHandler,即 ICommandHandler&lt;SomeCommand&gt;,而您尝试将其强制转换为 ICommandHandler&lt;ICommand&gt;,而这是不同的类型。

【讨论】:

    【解决方案4】:

    转换失败,因为 ICommandHandler&lt;SomeCommand&gt; 不是 ICommandHandler&lt;ICommand&gt;。有关更多详细信息和示例,请参阅here

    as 在实例不属于指定类型时仅返回 null,而强制转换则抛出 InvalidCastexception

    【讨论】:

      【解决方案5】:

      变量c is a 为null。它不会抛出,因为这就是使用“as”的意思。换句话说,实例 h 不是 ICommandHandler 的实例。

      下一行抛出,因为您试图将 SomCommandHandler 实例强制转换为 ICommandHandler 实例

      有意义吗?

      【讨论】:

        猜你喜欢
        • 2011-09-10
        • 1970-01-01
        • 2015-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-18
        相关资源
        最近更新 更多