2010-08-30 14 views
5

У меня есть класс с некоторыми функциями, которые реалистично являются «вспомогательными» методами, которые клиентский код мог бы сделать с другими свойствами/методами общедоступного доступа, и я не знаю, должен ли я определять их как свойства с помощью геттера , методы экземпляра или статические методы, которые принимают экземпляр в качестве параметра. Кроме того, у меня также есть интерфейс, извлеченный из класса, который используется почти везде, кроме конструкции, чтобы мой код мог использовать любой класс, реализованный против интерфейса.Вспомогательные методы в C#: статические или нестатические?

Вопрос в том, что лучше всего с точки зрения дизайна? Например, как средство получения инициала из этого класса:

class Person : IPerson { 
    private string name; 

    public string Name { get { return this.name; } } 

    // Property with getter 
    public string Initial { get { return this.name.Substring(0,1); } } 

    // Instance method 
    public string GetInitial { return this.name.Substring(0,1); } 

    // Static method 
    public static string GetInitial(IPerson person) { 
    return person.Name.Substring(0,1); 
    } 
} 

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

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

Означает ли это, не стоит ли предлагать классы, чтобы указать, как рассчитываются вспомогательные методы?

РЕДАКТИРОВАТЬ: Незначительные стороны, почему бы не добавить SO, чтобы использовать теги лучших практик?

+0

Похоже, пока нет ярлыков лучших практик. Для создания новых тегов вам нужна репутация не менее 1500 человек. – M4N

+0

Это странно .. определенно было, я использовал его в прошлом. – Flynn1179

+2

Смерть мета-тегов (например, лучшие практики): http://blog.stackoverflow.com/2010/08/the-death-of-meta-tags/ – M4N

ответ

10

Как насчет метода расширения?

namespace IPersonExtensions 
{ 
    public static class IPersonExtensionClass 
    { 
     public static string Initial(this IPerson @this) 
     { 
      return @this.name.Substring(0, 1); 
     } 
    } 
} 

Используйте это так:

string initial = person.Initial(); 

Таким образом, вы можете поделиться реализации без наследования или переписать код. Использование отдельного пространства имен позволяет пользователям выбирать, хотите ли они использовать этот код или нет.

+0

Не думал об этом ... хотя я предполагаю, что метод, вероятно, должен вернуть строку :) – Flynn1179

+3

Кажется, что Flynn создает этот класс с нуля. Если это так, метод расширения не должен использоваться, поскольку у вас есть доступ к исходному коду. Методы расширения следует использовать, если вы не можете изменить или расширить базовый класс. Общие руководства по MSDN http://msdn.microsoft.com/en-us/library/bb383977.aspx «В общем, мы рекомендуем применять методы расширения экономно и только тогда, когда вам нужно. Когда это возможно, клиентский код, который должен расширять существующий тип должен сделать это, создав новый тип, полученный из существующего типа ». – sgriffinusa

+0

@Flynn: Я должен был исправить это, когда вы вводили свой комментарий. :) –

1

Я иду туда и обратно, но я начинаю склоняться к их созданию не статичный.

Корпус для статического: Заставляет вас объявлять, что функция не использует переменные-члены и оставляет ее без гражданства. Если вы случайно позволите государству ползти, требуя переменные-члены, компилятор предупредит вас, и вы должны принять конкретное решение.

Корпус для функции-члена: Статические функции трудно унаследовать, поэтому изменить поведение сложно. Делает тестирование сложнее, так как сложнее заменить эту функцию, чтобы проверить что-то еще. Скажем, у вас было что-то, что использовало Initial, и вы хотели вернуть что-то конкретное для теста ...

В качестве стороннего (и экстремального примера) некоторые из моих расширений используют контейнер IOC для поиска конкретного класса и вызова член на нем.

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