C# 作为对象参数传递时发生无效的强制转换异常

C# 作为对象参数传递时发生无效的强制转换异常,c#,casting,C#,Casting,假设我有两个类,其中一个可以转换为另一个: public class Foo { } public class Bar { public static implicit operator Foo(Bar bar) => new Foo(); } 现在我有了一个方法,该方法希望将一个对象作为参数,并将其强制转换为Foo public void DoSomething(object o) { var foo = (Foo)o; /* Do something with

假设我有两个类,其中一个可以转换为另一个:

public class Foo { }

public class Bar
{
    public static implicit operator Foo(Bar bar) => new Foo();
}
现在我有了一个方法,该方法希望将一个对象作为参数,并将其强制转换为
Foo

public void DoSomething(object o)
{
    var foo = (Foo)o;
   /* Do something with foo here */
}
现在我这样称呼这个方法:

var bar = new Bar();
var foo = (Foo)bar;

DoSomething(foo);
DoSomething(bar);
当调用
DoSomething(foo)
按预期工作时,调用
DoSomething(bar)
抛出一个
InvalidCastException
。为什么运行时不能在第二个方法调用中使用用户定义的类型转换运算符

为什么运行时不能在第二个方法调用中使用用户定义的类型转换运算符

因为编译器没有在执行时执行。。。编译器(而不是运行时)会注意到用户定义的转换。除非该值真的是一个
Foo
,否则您得到的转换基本上总是失败的

public void DoSomething(object o)
{
    var foo = (Foo)o;
   /* Do something with foo here */
}
现在,解决这个问题的方法是使用动态键入。如果将方法参数设置为
动态
类型,那么编译器将在执行时运行(在某种程度上),并找到您的转换

例如:

using System;

public class Foo { }

public class Bar
{
    public static implicit operator Foo(Bar bar) => new Foo();
}

class Test
{
    static void Main(string[] args)
    {
        var bar = new Bar();
        var foo = (Foo)bar;

        DoSomething(foo);
        DoSomething(bar);
    }

    static void DoSomething(dynamic o)
    {
        var foo = (Foo) o;
    }
}
当然,如果您可以将参数的编译时类型改为
Foo
,那就更好了。。。你有什么理由不能那样做吗?请注意,如果您根本无法更改参数类型,则始终可以在方法中转换为
dynamic

static void DoSomething(object o)
{
    var foo = (Foo) (dynamic) o;
}

我无法更改参数类型,因为它必须与委托匹配。@ThomasSchremser:您可以使用方法组转换创建一个
操作
,该方法接受
动态
-在我回答的主要示例中,您可以使用
操作=DoSomething例如。