查找接口实例背后的具体类型(Finding the Concrete Type behind an

2019-06-26 11:17发布

为了削减长话短说我有执行上的传递中作为对象实例给定类型任务的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的实例的基础混凝土类型?

有些人也许会使用抽象类建议,但是这是我的坏榜样的只是限制。 变量将原本声明为一个接口实例。

Answer 1:

Type objectType = myObject.GetType();

还是应该给你具体的类型,根据你的榜样。



Answer 2:

你在做什么是真正床的设计,但你不必使用反射,你可以检查它像这样

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
}


Answer 3:

我不得不承认对糟糕的设计。 如果你有一个接口,它应该是因为你需要利用一些常见的功能,而不必考虑具体的实现是什么。 鉴于你例如,它听起来就像是方法的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);


Answer 4:

你永远不能拥有一个接口的实例。 所以,确定是否你正在处理一个接口或一个具体类型是不可能的,因为你将永远是处理具体类型。 所以,我不知道你的问题使任何意义。 究竟什么是你想干什么,为什么?



Answer 5:

也许你正在寻找的就是运营商

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
}


文章来源: Finding the Concrete Type behind an Interface instance