如何在没有IConvertible的情况下确定是否可以将对象强制转换为其他类型

时间:2015-11-05 11:21:42

标签: c# casting

我有两个不相关的类:一个不是从另一个派生的。 这些类不实现IConvertible 。这就是This answer不起作用的原因。

幸运的是,从一个类到另一个类有一个隐式类操作符。

示例:考虑   - System.Data.Entity.DbSet   - System.Data.Entity.DbSet。

隐式演员:

public static implicit operator DbSet (DbSet<TEntity> entry)

以下作品:

DbSet<MyClass> x = new DbSet<MyClass>();
DbSet y = (DbSet) x;         // ok, x properly cast to y

以下不起作用:

object x = new DbSet<MyClass>();
object y1 = x as DbSet;      // y1 is null, because not derived from DbSet
object y2 = (DbSet) x;       // throws InvalidCastException

那么可以检查一个对象是否可以转换为另一个对象而不抛出异常吗?

2 个答案:

答案 0 :(得分:0)

您应该能够使用反射搜索转换方法:

object set = new DbSet<MyClass>();
var conv = set.GetType().GetMethod("op_Implicit", BindingFlags.Static | BindingFlags.Public, null, new[] { set.GetType() }, null);
if (conv != null && conv.ReturnType == typeof(DbSet))
{
    var rawSet = (DbSet)conv.Invoke(null, new object[] { set });
}

答案 1 :(得分:0)

李回答了一个问题。我测试它是通过创建一个扩展方法来尝试将任何对象强制转换为任何类型,只要该对象具有对所请求类型的隐式或显式强制转换操作符。

public static class ObjectExtensionTryCast
{
    public static bool TryCast<T>(this object o, out T castedValue)
    {
        MethodInfo castMethod = new string[] { "op_Implicit", "op_Explicit" }
            .Select(methodName => o.GetType()
                .GetMethod(methodName, BindingFlags.Static | BindingFlags.Public, null, new[] { o.GetType() }, null))
            .Where(method => method.ReturnType == typeof(T))
            .FirstOrDefault();
        bool canCast = castMethod != null;
        castedValue = canCast ?
            (T)castMethod.Invoke(null, new object[] { o }) :
            default(T);
        return canCast;
    }
}

用法:

object o = GetMyObject();
int i;
System.Drawing.Point p;
DBSet dbSet;

bool intCasted = o.TryCast(out i);
bool pointCasted = o.TryCast(out p);
bool dbSetCasted = o.TryCast(out dbSet);