2008-10-20 2 views
8

У меня есть вопрос с плавными интерфейсами.Свободные интерфейсы в C#

У нас есть несколько объектов, которые используются в качестве объектов параметров для интерфейса SQL, вот пример:

using (DatabaseCommand cmd = conn.CreateCommand(
    "SELECT A, B, C FROM tablename WHERE ID = :ID", 
    SqlParameter.Int32(":ID", 1234))) 
{ 
    ... 
} 

Для некоторых из этих параметров, я хотел бы включить некоторые специализированные варианты, но вместо добавления больше свойств к методу Int32 (который является лишь одним из многих), я думал, что я буду изучать свободные интерфейсы.

Вот пример, где я добавил, что я ищу в:

SqlParameter.Int32(":ID", 1234).With(SqlParameterOption 
    .Substitute 
    .Precision(15) 
) 

Я знаю, что эти два варианта не имеет смысла для этого типа параметра, но это не то, что речь идет о.

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

Что делать, если я их переупорядочу?

SqlParameter.Int32(":ID", 1234).With(SqlParameterOption 
    .Precision(15) 
    .Substitute 
) 

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

Как это сделать? Неужели я полностью ошибаюсь?

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

SqlParameter.Int32(":ID", 1234).With 
    .Precision(15) 
    .Substitute 

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

советы и некоторые хорошие URL, было бы только приветствовать, я рыскал в течение многих примеров, но они, как правило, показывают примеры, как это:

order 
    .AddFreeShipping() 
    .IncludeItem(15) 
     .SuppressTax(); 

(снят с this page)


Редактировать: Последующие меры после ответов От @marxidad:

class SqlParameterOption 
{ 
    public SqlParameterOption Precision(int p) {/* ... */; return this;} 
    public SqlParameterOption Substitute() {/* ... */; return this;} 
    /* ... */  
} 

/* ... */ 
SqlParameter.Int32(":ID", 1234).With(new SqlParameterOption() 
              .Precision(15) 
              .Substitute()); 

При таком подходе С должен был бы взять объект и применить его к параметру. Я в порядке с этим.

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

SqlParameter.Int32(":ID", 1234).With 
           .Precision(15) 
           .Substitute()); 

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

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

Мое решение: Как @marxidad говорит, если изменения носят необратимый характер, и потенциально может быть предметом обращения, создание государства и не в какой-то момент с исключением так я пойду.

Однако в этом случае я использую более простой подход, который напрямую изменяет объект SqlParameter.

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

SqlParameter.Int32(":ID", 1234).With 
           .Precision(15) 
           .Substitute()); 

Edit: Гах, вот как это происходит, когда я сосредоточиться только на одну вещь.

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

SqlParameter.Int32(":ID", 1234).With(new SqlParameterOption() 
              .Precision(15) 
              .Substitute()); 

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

ответ

8

SqlParameterOption's методы могут быть все методы экземпляра, который возвращает тот же объект:

class SqlParameterOption 
{ 
    public SqlParameterOption Precision(int p) {/* ... */; return this;} 
    public SqlParameterOption Substitute() {/* ... */; return this;} 
    /* ... */  
} 

/* ... */ 
SqlParameter.Int32(":ID", 1234).With(new SqlParameterOption() 
              .Precision(15) 
              .Substitute()); 

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

1

Возможно, вы перегрузили методы. Например, если он был Substitute(). Обычно у вас не могут быть как статические, так и экземплярные версии метода, но методы расширения могут быть полезны ... но если две версии Substitute имеют разные значения, было бы проще просто возвращать разные типы, поэтому что два варианта Substitute() не могут конфликтовать.

+0

В этом случае не было бы конфликта смысла, вопрос был больше о том, как я упорядочиваю код, чтобы получить то, что хочу, синтаксически. Создание экземпляра объекта option решает эту проблему, как показано marxidad. – 2008-10-20 11:36:41

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