简体   繁体   English

查找Interface实例后面的具体类型

[英]Finding the Concrete Type behind an Interface instance

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. 简而言之,我有一个C#函数,它对作为Object实例传入的给定Type执行任务。 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. 传入类实例时,一切正常。但是,当对象被声明为接口时,我真的很想找到具体的类并对该类类型执行操作。

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(). 我希望PerformAction中的代码使用Reflection来反对它的参数,看看它不仅仅是IA的一个实例,而是它的B实例,并通过GetProperties()查看属性“b”。 If I use .GetType() I get the Type of IA - not what I want. 如果我使用.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. 有些人可能会建议使用Abstract类,但这只是我的坏例子的限制。 The variable will be originally declared as an interface instance. 该变量最初将被声明为接口实例。

Type objectType = myObject.GetType();

根据你的例子,还应该给你具体的类型。

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
}

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

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? 你究竟想做什么以及为什么?

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM