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

时间:2009-07-21 15:21:24

标签: c# interface types concrete

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

这是无处不在的坏例子(金属外壳不正确等等):

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中的代码使用Reflection来反对它的参数,看看它不仅仅是IA的一个实例,而是它的B实例,并通过GetProperties()查看属性“b”。如果我使用.GetType(),我会得到IA的类型 - 而不是我想要的。

PerformAction如何确定IA实例的基础Concrete Type?

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

5 个答案:

答案 0 :(得分:72)

Type objectType = myObject.GetType();

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

答案 1 :(得分: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
}

答案 2 :(得分: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);

答案 3 :(得分:3)

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

答案 4 :(得分:1)

也许您正在寻找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
}