2011-12-27 3 views
0
private void SomeMethod(DerivedA something) {...} 
private void SomeMethod(DerivedB something) {...} 
private void SomeMethod(DerivedC something) {...} 


BaseClass bc = somevariable; 
if (bc is DerivedA) Somemethod(bc as DerivedA) 
else if (bc is DerivedB) Somemethod(bc as DerivedB) 
else if (bc is DerivedC) Somemethod(bc as DerivedC) 
... 
else if (bc is DerivedZZ) Somemethod(bc as DerivedZZ) 

В .NET 3.5 должен быть более простой способ, нет?Простой способ проверки и вызова перегруженного метода

+0

Является ли 'SomeMethod' чем-то, что должен делать объект, или это что-то внешнее усилие делает с/объектом? –

+0

Чтобы уточнить, класс, с которым я работаю, не является DerivedX, но действует на DerivedA ... DerivedZ и вызывает методы для разных действий. В основном, я пытаюсь избежать большого оператора switch (или if/else) и решил сделать SomeMethod (Производный A). Я мог бы сделать SomeMethodActOnDerivedA, SomeMethodActOnDerivedB и т. Д. Подумайте об этом как странице с различными пользовательскими элементами управления, и эти пользовательские элементы управления имеют общий базовый класс, но их нужно заполнять и действовать отдельно. –

+0

Возможно, typeof() может выполнить эту работу за вас? –

ответ

4

Не подходит ли метод SomeMethod для вашего класса?

Если DerivedA, DerivedB и т. Д. Все имеют один и тот же родительский объект, то вы можете создать этот метод как метод виртуального члена в родительском классе и переопределить его в классах, которые наследуются от него. (Это не относится к .NET 3.5 -или любой другой .NET версии whatsoever-, это только одна из основных особенностей ООП)

Как это:

public class BaseClass 
{ 
    public virtual void SomeMethod() 
    { 
     Console.WriteLine ("BaseClass"); 
    } 
} 

public class DerivedA : BaseClass 
{ 
    public override SomeMethod() 
    { 
     Console.WriteLine("DerivedA"); 
    } 
} 

public class DerivedB : BaseClass 
{ 
    public override SomeMethod() 
    { 
     Console.WriteLine ("DerivedB"); 
    } 
} 

BaseClass bc = someVariable; 

bc.SomeMethod(); 
+0

+1. Или даже сделать его абстрактным в базе ... – Cameron

+0

Согласен; Полиморфизм кажется хорошим кандидатом здесь –

+0

См. комментарий выше. Класс, с которым я работаю, не выводится, а действует на производные объекты. –

1
public class BaseClass { 
    public virtual void SomeMethod() 
    { 
    } 
}; 

public class DerivedA : BaseClass { 
    public override void someMethod() 
    { //Do DerivedA things 
    } 
}; 
public class DerivedB : BaseClass { 
    public override void someMethod() 
    { //Do DerivedB things 
    } 
}; 
public class DerivedC : BaseClass { 
    public override void someMethod() 
    { //Do DerivedC things 
    } 
}; 

Затем вы можете сделать :

BaseClass bc = new BaseClass(); 

или

BaseClass bc = new DerivedA(); 

или

BaseClass bc = new DerivedB(); 

или

BaseClass bc = new DerivedC(); 

и просто позвонить:

bc.SomeMethod(); 

Даже тип BC быть BaseClass, если экземпляр, как производный, производный метод будет вызван. Это означает наследование и полиморфизм.

этот код в равной степени соответствует вашим.

Даже ваш, вы можете лучше использовать typeof(); ;)

+0

См. Комментарий выше. Класс, с которым я работаю, не является производным, а действует на производные объекты. –

0

Похоже, вам нужно немного переосмыслить, как вы поступаете; если у вас есть другой класс, который должен использовать этот BaseClass, не зная, какой тип производного класса он содержит, пока вы не вызовете метод, который кажется неэффективным.

public abstract class BaseClass 
{ 
    public abstract void InitializeAndDoOtherStuff(); 
} 

public abstract class DerivedA 
{ 
    public overload void InitializeAndDoOtherStuff() 
    { 
     // Initializes the control, pass whatever you need into this method, etc) 
    } 
} 

В этом случае, ваш код выглядит так:

BaseClass bc = someVariable; 
bc.InitializeAndDoOtherStuff(); 

ИЛИ

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

public class DerivedA : BaseClass, IControlA { } 
public class DerivedB : BaseClass, IControlB { } 
... 

И тогда у вашего другого класса есть перегрузка s как так:

public void SomeMethod(IControlA control) { } 
public void SomeMethod(IControlB control) { } 
... 

Затем в коде было бы так же легко, как:

BaseClass bc = someVariable; 
SomeMethod(bc); 

И перегрузки резолюции будет заботиться о нем, потому что соответствующий интерфейс только на одном производном классе.

0

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

this.GetType().InvokeMember("SomeMethod", // Method name 
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, 
    null, // DefaultBinder 
    this, // object to call the method on 
    new[]{ bc } // parameters to the method 
    ); 

если SomeMethod не метод общественного экземпляра, вам необходимо соответствующим образом адаптировать BindingFlags.

+0

Я не могу перепроектировать классы, которые другие люди решили сделать так, как они выбрали. Исходя из моего первоначального вопроса, зная, что я не могу изменить код других людей, есть ли что-то, что можно сделать, чтобы сделать это лучше? –

+0

Ну, если вы не можете изменить существующий код, напишите свой собственный слой абстракции для существующего кода, или если это ваша единственная точка боли, используйте рефлексию, чтобы сэкономить на некотором наборе текста – kev

Смежные вопросы