如何将C#对象解包为动态类型

11

我想要做这样的事情:

void someMethod(TypeA object) { ... }

void someMethod(TypeB object) { ... }

object getObject()
{
    if (...) return new TypeA();
    else return new TypeB();
}

object obj = getObject();
(obj.GetType()) obj;  // won't compile
someMethod(obj);

很明显我在这里感到困惑。我知道通过编写条件语句可以使它起作用。
if (obj.GetType() == typeof(TypeA)) obj = (TypeA)obj;
else if (obj.GetType() == typeof(TypeB)) obj = (TypeB)obj;

--但是在运行时难道没有其他方法吗?

编辑 我同意这似乎不是最佳的设计选择,以下是上述代码的背景。 上面的代码是用于Mongo DB的Repository基类。 我希望它能够处理不同类型的表格。 因此,someMethod()实际上是remove;而TypeA和TypeB分别是ObjectID和 Guid ;底部的代码是一种与类型无关的 remove 方法,它接受字符串作为ID; getObject()是解析ID参数的方法。


你正在混淆类型 T 和与之关联的运行时类型信息:typeof(T)。它们不是同一件事,也不能相互替换。 - Kirk Woll
可能有更好的设计选择,但您在帖子中没有提及代码的实际目标。如果您让我们知道您尝试使用此代码实现什么目标,也许我们可以为您提供更好、完全不同的解决方案。 - John Fisher
@Kirk Woll,我知道区别,我只是想说明一下我试图做的事情。 - McGarnagle
@John Fisher,已添加上下文。我认为这可能是一个“代码审查”交流的问题,但如果您有想法,我很乐意将其作为一个单独的问题开放。 - McGarnagle
1
看看Massive,你会发现很多好的想法。 - Robert Harvey
1个回答

20

如果您使用的是.NET 4和C# 4,则可以使用dynamic来实现此操作:

dynamic obj = GetObject();
SomeMethod(obj);
否则,你将不得不使用反射来查找和调用正确的方法。重载决议(对于非dynamic类型)在编译时执行。
(请注意,除非TypeATypeB是结构体,否则你无论如何都不会拆箱...)

@RobertHarvey:根据问题的描述方式,它在同一类型中选择重载是不可行的。 - Jon Skeet
我不知道重载解析还涵盖了 dynamic 对象的运行时类型。 - Robert Harvey
1
@RobertHarvey:这就是“dynamic”的全部意义 - 实际上几乎所有内容都被延迟到了执行时间,使用对象的实际类型。 - Jon Skeet
@RobertHarvey:唯一不能扩展到dynamic的是扩展方法;这些只在编译时可用。 - Gabe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接