C# 查找接口实例背后的具体类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1159906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Finding the Concrete Type behind an Interface instance
提问by
To cut a long story short I have a C# function that performs a task on a given Type that is passed in as an Object instance. All works fine when a class instance is passed in. However, when the object is declared as an interface I'd really like to find the concrete class and perform the action upon that class type.
长话短说,我有一个 C# 函数,它对作为 Object 实例传入的给定类型执行任务。当传入一个类实例时,一切正常。但是,当对象被声明为接口时,我真的很想找到具体的类并对该类类型执行操作。
Here is the ubiquitous bad example (resplendent with incorrect property casing etc):
这是无处不在的坏例子(华丽的属性大小写不正确等):
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
}
I'd like the code in PerformAction to use Reflection against it's parameter and see that it's not just an instance of IA but that it's an instance of B and to see the property "b" via GetProperties(). If I use .GetType() I get the Type of IA - not what I want.
我希望 PerformAction 中的代码对它的参数使用反射,并看到它不仅是 IA 的实例,而且是 B 的实例,并通过 GetProperties() 查看属性“b”。如果我使用 .GetType() 我得到 IA 的类型 - 不是我想要的。
How can PerformAction determine the underlying Concrete Type of the instance of IA?
PerformAction 如何确定 IA 实例的底层具体类型?
Some might be tempted to suggest using an Abstract class but that is just the limitation of my bad example. The variable will be originally declared as an interface instance.
有些人可能会建议使用 Abstract 类,但这只是我的坏例子的限制。该变量最初将被声明为接口实例。
采纳答案by Stan R.
Type objectType = myObject.GetType();
Should still give you the concrete type, according to your example.
根据你的例子,仍然应该给你具体的类型。
回答by Chris Johnston
You can never have instances of an Interface. So determining whether you are dealing with an interface or a concrete type is not possible since you will always be dealing with a concrete type. So I am not sure you question makes any sense. What exactly are you trying to do and why?
你永远不能拥有接口的实例。因此,确定您是在处理接口还是具体类型是不可能的,因为您将始终处理具体类型。所以我不确定你的问题是否有意义。你到底想做什么,为什么?
回答by Arsen Mkrtchyan
What are you doing is really bed design but you don't have to use reflection you can check it like this
你在做什么真的是床设计,但你不必使用反射你可以像这样检查它
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
}
回答by kova
Maybe you are looking for the is operator
也许您正在寻找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
}
回答by jrista
I have to agree about the bad design. If you have an interface, it should be because you need to utilize some common functionality without caring what the concrete implementation is. Given you're example, it sounds like the PerformAction method should actually be a part of the interface:
我不得不同意糟糕的设计。如果你有一个接口,那应该是因为你需要使用一些常用的功能而不关心具体的实现是什么。鉴于您是示例,听起来 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);