2012-05-31 9 views
5

Jestem prawie pewien, że zadawano to wcześniej, ale niestety jedyną rzeczą, którą znalazłem, było this, które nie było rozwiązaniem dla mnie. W moim obecnym projekcie zrobić coś takiego:Jak mogę rzutować obiekt dynamicznie?

private object obj; 

private void Initialize() 
{ 
    obj.Initialize(); 
} 

private void CreateInstanceA() 
{ 
    obj = Activator.CreateInstance(typeof(MyClassA)); 
} 

private void CreateInstanceB() 
{ 
    obj = Activator.CreateInstance(typeof(MyClassB)); 
} 

Ten kod nie działa oczywiście, bo nie zostały oddane obj ponieważ jej typ zmienia się dynamicznie.

Jak mogę rzucić go dynamicznie?

+4

Wygląda na to, że nie byłoby to najlepsze rozwiązanie. Coś mi pachnie. Jaki jest większy kontekst tego, co próbujesz osiągnąć? – FishBasketGordo

+0

Oprócz inicjowania tego, co jeszcze zamierzasz zrobić z 'obj'? –

+0

@RaymondChen Właśnie zrobiłem prosty projekt WinForm, aby przetestować biblioteki klas. – Leri

Odpowiedz

9

trzy opcje:

  • Jeśli kontrolować obu klas, można uczynić je wdrożyć wspólny interfejs, który zawiera wszystko, czego potrzebujesz, zrób to - i oddane do interfejsu
  • jeśli jesteś używając C# 4 i .NET 4, możesz używać dynamicznego pisania - po prostu zadeklaruj zmienną jako private dynamic obj;, a ona skompiluje i znajdzie właściwą metodę w czasie wykonywania.
  • W przeciwnym razie użyj odbicia, aby znaleźć i wywołać metodę.

Zasadniczo odlewania na podstawie typu czas wykonania nie ma sensu, w ramach punktu odlewu jest dać kompilator więcej informacji ... a ty po prostu nie ma, że ​​w ta sprawa.

Pierwsza opcja jest zdecydowanie najładniejsza, jeśli możesz ją osiągnąć.

+1

a co z Injection Dependency Injection –

+1

Dependency Injection bez interfejsów/abstrakcyjnej klasy bazowej? W jaki sposób? Jeśli można zdefiniować interfejsy, najpierw wystarczy scenariusz – Tilak

+0

Czy klasa bazowa nie byłaby lepsza, w przeciwieństwie do interfejsu? Jest to * is-a * (klasa abstrakcyjna), w przeciwieństwie do * can-do * (interface). Zakładając, że typy są podobne oczywiście – mattytommo

0

Zakładam, że CreatInstanceB() powinien faktycznie używać MyClassB, prawda?

W takim przypadku można użyć:

((MyClassA)obj).Initialize(); 

...

((MyClassB)obj).Initialize(); 

Albo można zrobić interfejs, który posiada metodę Initialize i zdefiniować jako obj tego interfejsu.

+0

Myślę, że w metodzie inicjowania MyClassA lub MyClassB nie są znane, co jest punktem w pytaniu – Tilak

+0

Tak, masz rację. Edytowałem pytanie. Lepiej użyj słowa kluczowego 'dynamic', jak zasugerował @ JonSkeet. – Leri

+0

To prawda, tęskniłem. Zawsze możemy polegać na Panu Skeecie. – Slugart

Powiązane problemy