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实例传入的给定Type执行任务。传入类实例时,一切正常。但是,当对象被声明为接口时,我真的很想找到具体的类并对该类类型执行操作。
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中的代码使用Reflection来反对它的参数,看看它不仅仅是IA的一个实例,而是它的B实例,并通过GetProperties()查看属性“b”。如果我使用.GetType(),我会得到IA的类型 - 而不是我想要的。
How can PerformAction determine the underlying Concrete Type of the instance of IA?
PerformAction如何确定IA实例的基础Concrete Type?
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类,但这只是我的坏例子的限制。该变量最初将被声明为接口实例。
5 个解决方案
#1
Type objectType = myObject.GetType();
Should still give you the concrete type, according to your example.
根据你的例子,还应该给你具体的类型。
#2
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
}
#3
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);
#4
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?
您永远不能拥有接口的实例。因此,确定您是在处理接口还是具体类型是不可能的,因为您将始终处理具体类型。所以我不确定你的问题是否有意义。你究竟想做什么以及为什么?
#5
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
}
#1
Type objectType = myObject.GetType();
Should still give you the concrete type, according to your example.
根据你的例子,还应该给你具体的类型。
#2
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
}
#3
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);
#4
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?
您永远不能拥有接口的实例。因此,确定您是在处理接口还是具体类型是不可能的,因为您将始终处理具体类型。所以我不确定你的问题是否有意义。你究竟想做什么以及为什么?
#5
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
}