查找接口实例背后的具体类型
Posted
技术标签:
【中文标题】查找接口实例背后的具体类型【英文标题】:Finding the Concrete Type behind an Interface instance 【发布时间】:2010-11-12 16:38:48 【问题描述】:长话短说,我有一个 C# 函数,它对作为 Object 实例传入的给定类型执行任务。当传入类实例时,一切正常。但是,当对象被声明为接口时,我真的很想找到具体的类并对该类类型执行操作。
这是一个普遍存在的坏例子(带有错误的属性大小写等):
public interface IA
int a get; set;
public class B : IA
public int a get; set;
public int b get; set;
public class C : IA
public int a get; set;
public int c get; set;
// snip
IA myBObject = new B();
PerformAction(myBObject);
IA myCObject = new C();
PerformAction(myCObject);
// snip
void PerformAction(object myObject)
Type objectType = myObject.GetType(); // Here is where I get typeof(IA)
if ( objectType.IsInterface )
// I want to determine the actual Concrete Type, i.e. either B or C
// objectType = DetermineConcreteType(objectType);
// snip - other actions on objectType
我希望 PerformAction 中的代码对其参数使用反射,并看到它不仅是 IA 的实例,而且是 B 的实例,并通过 GetProperties() 查看属性“b”。如果我使用 .GetType() 我会得到 IA 的类型 - 这不是我想要的。
PerformAction 如何确定 IA 实例的底层具体类型?
有些人可能会建议使用 Abstract 类,但这只是我的坏例子的限制。该变量最初将被声明为接口实例。
【问题讨论】:
【参考方案1】:您永远不能拥有接口的实例。因此,确定您是在处理接口还是具体类型是不可能的,因为您将始终处理具体类型。所以我不确定你的问题是否有意义。你到底想做什么,为什么?
【讨论】:
【参考方案2】:你在做的是真正的床设计但你不必使用反射你可以像这样检查它
void PerformAction(object myObject)
B objectType = myObject as B; // Here is where I get typeof(IA)
if ( objectType != null )
//use objectType.b
else
//Same with A
// snip - other actions on objectType
【讨论】:
这仍然是相当糟糕的设计,因为您仍然依赖于具体类型。这在很大程度上违背了最初拥有接口的目的......【参考方案3】:Type objectType = myObject.GetType();
根据您的示例,仍应为您提供具体类型。
【讨论】:
是的,调用“myObject.GetType()”永远不会返回接口类型。PerfomAction
的参数是object
,但是他不能这样做:例如IA.getType()
。【参考方案4】:
也许您正在寻找is operator
void PerformAction(object myObject)
if (myObject is B)
B myBObject = myObject as B;
myBObject.b = 1;
if (myObject is C)
C myCObject = myObject as C;
myCObject.c = 1;
// snip - other actions on objectType
【讨论】:
您正在投射两次。直接使用as
运算符并稍后检查是否为空【参考方案5】:
我必须同意糟糕的设计。如果你有一个接口,那应该是因为你需要使用一些通用的功能,而不关心具体的实现是什么。以您为例,听起来 PerformAction 方法实际上应该是接口的一部分:
public interface IA
int a get; set;
void PerformAction();
public class B: IA
public int a get; set;
public int b get; set;
public void PerformAction()
// perform action specific to B
public class C : IA
public int a get; set;
public int c get; set;
public void PerformAction()
// perform action specific to C
void PerformActionOn(IA instance)
if (instance == null) throw new ArgumentNullException("instance");
instance.PerformAction();
// Do some other common work...
B b = new B();
C c = new C();
PerformActionOn(b);
PerformActionOn(c);
【讨论】:
以上是关于查找接口实例背后的具体类型的主要内容,如果未能解决你的问题,请参考以下文章