查找接口实例背后的具体类型

问题描述 投票:0回答:5
长话短说,我有一个 C# 函数,它对作为对象实例传入的给定类型执行任务。当传入类实例时,一切正常。但是,当对象被声明为接口时,我真的很想找到具体的类并对该类类型执行操作。

这是无处不在的坏例子(典型的属性大小写不正确等):

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 实例的底层具体类型?

有些人可能会建议使用抽象类,但这只是我的坏例子的局限性。该变量最初将被声明为接口实例。

c# interface types concrete
5个回答
102
投票
Type objectType = myObject.GetType();

根据您的示例,仍然应该为您提供具体类型。


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);
    

5
投票
你所做的设计确实很糟糕,但你不必使用反射。相反,你可以这样检查:

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 }
    

4
投票
你永远不可能拥有接口的实例。因此,无法确定您正在处理接口还是具体类型,因为您将始终处理具体类型。所以我不确定你的问题是否有意义。您到底想做什么?为什么?


3
投票
也许您正在寻找

is 运算符

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 }
    
© www.soinside.com 2019 - 2024. All rights reserved.