Подтвердить что ты не робот

Поиск конкретного типа за экземпляром интерфейса

Короче говоря, у меня есть функция С#, которая выполняет задачу по заданному типу, который передается как экземпляр объекта. Все работает отлично, когда экземпляр класса передается. Однако, когда объект объявлен как интерфейс, мне бы очень хотелось найти конкретный класс и выполнить действие над этим типом класса.

Вот вездесущий плохой пример (блистательный с неправильным корпусом свойств и т.д.):

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 to it и видел, что это не просто экземпляр IA, а экземпляр B, а также свойство b с помощью GetProperties(). Если я использую .GetType(), я получаю тип IA - не то, что я хочу.

Как может PerformAction определить базовый тип конкретного экземпляра IA?

У некоторых может возникнуть соблазн предложить использовать абстрактный класс, но это лишь ограничение моего плохого примера. Эта переменная будет первоначально объявлена ​​как экземпляр интерфейса.

4b9b3361

Ответ 1

Type objectType = myObject.GetType();

Должен все же предоставить вам конкретный тип, в соответствии с вашим примером.

Ответ 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
}

Ответ 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);

Ответ 4

У вас никогда не будет экземпляров интерфейса. Поэтому определение того, имеете ли вы дело с интерфейсом или конкретным типом, невозможно, так как вы всегда будете иметь дело с конкретным типом. Поэтому я не уверен, что ваш вопрос имеет смысл. Что именно вы пытаетесь сделать и почему?

Ответ 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
}