2012-02-07 2 views
3

Я ищу способ получить возможные типы для повышения уровня объекта. Например: у меня есть элемент управления MyControl, который наследует Control. Теперь, когда объект типа MyControl отключен в Control, есть способ узнать, является ли он верхним типом объекта или когда он теперь получает тип (ы), в котором он может быть повышен (в данном случае MyControl) ? Я хочу, чтобы он был включен в MyControl (с Reflection) и получил свойство с отражением. Но я не знаю MyControl в том месте, где я должен это делать.Upcast a object

MyControl реализуется Видимый с новым. Теперь, когда я вызываю control.Visible = true, он вызовет Visible of Control, но я должен вызвать Visible of MyControl.

Благодарим за помощь.

+2

Я считаю, что вы поменялись смыслом и приведения к базовому типу понижающего приведения. Upcasting - это когда вы конвертируете из производного класса в базовый класс ** вверх ** иерархию наследования (например,'MyControl'' Control'). Downcasting - это противоположный путь, в котором вы бросаете ** вниз ** иерархию наследования. В C# upcasting неявно и что-то, что вам не нужно записывать в коде. –

ответ

2

Существует:

if (myControl is MyControl) 
{ 
    var m = (MyControl)myControl; 
} 

Это будет работать на любой части иерархии типов. Следующая проверка будет не работать, если сама переменная базового типа:

MyBaseControl myControl = null; 

if (myControl.GetType() == typeof(MyControl)) 
{ 

} 

Однако это звучит, как вы хотите, поведение перекрытых методов или свойств. В нормальной ситуации, вы бы переопределить Visible:

public override bool Visible 
{ 
    get { return true; } // Always visible in derived class. 
} 

Однако это только если базовый класс не запечатан и член вы хотите переопределить это abstract или virtual. Если это не так, то я бы придерживался приведения к производному типу ... не идеально, но не так много вариантов.

Это также звучит, как вы пытались скрыть базовый элемент вроде этого:

public new bool Visible 
{ 
    get { return true; } 
} 

Это работает только если у вас есть ссылка на самого типа. Если у вас есть ссылка на базовый тип, скрытие члена делает не работы, он не знает, член скрыт в производном типе:

MyBaseControl c = new MyDerivedControl(); 

bool vis = c.Visible; // Comes from MyBaseControl even if hidden in derived control. 

(В приведенном выше, если Visible были отменены, то это будет происходить из производного класса).

Update: делать все это во время выполнения, вы можете сделать следующее так долго, как вы знаете имена вещей, которые вы хотите, чтобы отразить:

class Program 
    { 
     static void Main(string[] args) 
     { 
      A a = new B(); 

      // Get the casted object. 
      string fullName = a.GetType().FullName; 
      object castedObject = Convert.ChangeType(a, Type.GetType(fullName)); 

      // Use reflection to get the type. 
      var pi = castedObject.GetType().GetProperty("Visible"); 

      Console.WriteLine(a.Visible); 
      Console.WriteLine((bool)pi.GetValue(castedObject, null)); 

      Console.Read(); 
     } 
    }  

    class A 
    { 
     public bool Visible { get { return false; } } 
    } 

    class B : A 
    { 
     public new bool Visible { get { return true; } } 
    } 
} 
+0

Я знаю это - но есть ли способ бросить, не зная MyControl - только, например, с отражением? – BennoDual

+0

@ t.kehl Я верю, что есть способ, дайте мне момент, чтобы проверить его. –

+0

@ t.kehl Обновлен мой ответ версией, которая предполагает, что вы знаете, что хотите называть 'Visible' для каждого элемента. Он поднимает ссылку на самый старший производный класс, а затем выполняет отражение против члена, которого вы хотите вызвать. –

0
Control control = (control)someControlOfTypeMyControl; 

if (control is MyControl) { 
    var myControl = (MyControl)control; 
    var propertyValue = myControl.SomeProperty; 
} 
+0

Я знаю это - но есть ли способ бросить, не зная MyControl - только, например, с отражением? – BennoDual

4

Вы также можете использовать это:

MyControl myControl = someControlOfTypeMyControl as MyControl 

if(myControl != null) 
{ 
    //your stuff 
} 

с «как» .NET Framework проверки, если элемент управления из этого типа и, если это возможно, чтобы бросить .NET Framework будет бросить и вернуться с типом MyControl, в противном случае он будет возвращать нуль.

Так в основном, его же, как и предыдущие ответы, но более чистый (имхо, вы можете думать иначе)

+1

Хотя OP скорее всего не получит этой проблемы, стоит отметить, что оператор 'as' работает только с ссылочными типами. –

+0

@Adam Houldsworth Да, спасибо, отметив эту деталь. ;) –

+0

Я знаю это - но есть ли способ бросить, не зная MyControl - только, например, с отражением? – BennoDual