2009-03-19 2 views
0

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

type1 implicitly casts to type0 
type2 implicitly casts to type0 
type3 implicitly casts to type0 

Operate (type0) 

и называют:

type1 a 
type2 b 
type3 c 

Operate (a) 
Operate (b) 
Operate (c) 

Есть ли проблемы с этой техникой? Производительность, четкость и т. Д.?

РЕДАКТИРОВАТЬ: Я также подразумеваю, что я использовал нестандартные заливки для типа без потери данных, просто удобство. Скажем, у вас есть класс Pixel, а затем отправьте экземпляр этого метода методу, который принимает Point2, автоматически отбрасывает пиксель в Point2.

ответ

2

Это совершенно нормальная практика.

Производительность разумная, я не верю, что есть какие-либо проблемы.

Ясность мудрая, из-за Intellisense у вас вряд ли будут проблемы с этим.

+0

Intellisense вам не поможет. Когда вы вводите метод Operate(), Intellisense сообщает только, что он принимает тип0. Вы не сможете сказать, что вы можете ввести тип1, если вы не откроете определение типа1. – foson

+0

На самом деле он просто нажимает клавиши вверх и вниз для прокрутки перегрузок, как только Intellisense покажет вам метод. –

+0

Очевидно, что это работает только для Visual Studio 2005 и выше, для любой другой среды IDE, и ваша точка может быть правильной. –

2

Кастинг обычно создает новый объект, который является ненужным в этом случае

Чем больше OOP способ сделать это будет через базовый класс или интерфейс.

class Type1 : IOperatableType {} 
class Type2 : IOperatableType {} 
class Type3 : IOperatableType {} 

void Operate (IOperatableType a) 

или

class Type1 : Type0 {} 
class Type2 : Type0 {} 
class Type3 : Type0 {} 

void Operate (Type0 a) 

Способ вызова (Работают в данном случае) зависит от того, с помощью методов и свойств его параметров. Если эти свойства/методы определены для всех типов (type1, type2, type3), рассмотрите возможность использования интерфейса, который определяет общую функциональность. Если реализация свойств и методов одинакова, сохраните себя от повторного кода и рассмотрите наследование от базового класса.

Кроме того, при попытке понять ваш код разработчики с большей вероятностью сначала рассмотрят диаграмму классов, которая позволяет им видеть взаимосвязь между классами или, по крайней мере, определение класса (которое будет отображать базовые типы и реализовано интерфейсы) вместо того, чтобы смотреть в (неявные/явные) операторы, чтобы увидеть, какой класс является допустимым для другого класса.

+0

Зависит от отношения между объектами. Если type2 является частным случаем типа 1, то полиморфизм - это путь. – dub

+0

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

+0

Спасибо, да, кастинг создает новые объекты, но в случае с классом Pixel, если у вас есть свойства X и Y, передавая его методу, который требует Point2, вам все равно придется создавать эти значения внутри метода, если не неявно бросать. –

3

Это основа того, как работают интерфейсы.

public interface IBlah { 
    void DoSomething(); 
} 
public class Type1 : IBlah { 
    void DoSomething() { /* implementation */ } 
} 
public class Type2 : IBlah { 
    void DoSomething() { /* implementation */ } 
} 
public class Type3 : IBlah { 
    void DoSomething() { /* implementation */ } 
} 

public class Foo { 
    void Operate(IBlah blah) { 
     blah.DoSomething(); 
    } 
} 
+0

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

+0

Если вам нужно добавить новый тип, даже тот, который не связан, он все равно будет работать. Например, если типы 1-3 являются типами автомобилей, тип 4 - это человек, а DoSomething() - это MoveForward(), если объект выполняет контракт интерфейса, он будет работать. –

+0

Хорошая точка, спасибо Крису. –

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