有一种"便宜而简单"的方法来判断对象是否为特定类型实现了显式/隐式转换运算符?

fos*_*ndy 9 c# casting

最好用一个例子来说明:

class Cat
{
}

class Dog
{
    public static implicit operator Cat(Dog d)
    {
        return new Cat();
    }
}
Run Code Online (Sandbox Code Playgroud)

我想告诉一个任意对象,我是否可以把它投射到Cat上.可悲的是,我似乎无法使用is/as运算符.

void Main()
{
    var d = new Dog();
    if (d is Cat) throw new Exception("d is Cat");
    var c1 = (Cat)d; // yes
    //var c2 = d as Cat; // Won't compile: Cannot convert type 'Dog' to 'Cat' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

}
Run Code Online (Sandbox Code Playgroud)

我希望避免使用try/catch(InvalidCastException),因为我可能会做很多这样做,这将是非常昂贵的.

有没有办法廉价而轻松地做到这一点?

编辑:感谢你们的答案 - 为所有人投票,希望我能给你们所有的Tick,但是它会向Marc提供最通用的解决方案(在ipod上打出奖金).然而,Jordao的解决方案设法磨练我需要的东西,而不是我要求的东西,所以这可能是我要去的.

Mar*_*ell 7

转换运算符不会被/ as检查.你需要使用反射来检查和调用所述运算符.我会写一个通用的静态类

static class Convert<TFrom,TTo> {}
Run Code Online (Sandbox Code Playgroud)

并在静态构造函数中检查方法,使用Delegate.CreateDelegate创建一个

Func<TFrom,TTo>
Run Code Online (Sandbox Code Playgroud)

并将其存储在静态字段中.然后您可以快速访问键入的方法:

public static TTo Convert(TFrom obj) { return del(obj); }
public static bool CanConvert { get { return del != null; } }
private static readonly Func<TFrom,TTo> del;
Run Code Online (Sandbox Code Playgroud)