Это хорошая практика, чтобы создать метод расширения, который никогда не использует расширенный объект? - PullRequest
0 голосов
/ 24 сентября 2010

В нашем проекте ASP.NET MVC у нас есть метод расширения HtmlHelper для создания статической карты Google.

public static MvcHtmlString StaticMap(this HtmlHelper helper, string address, string alt, int width, int height, int zoom)
{
    var src = new Uri("http://maps.google.com/maps/api/staticmap?markers=size:mid|color:red|{0}&zoom={1}&size={2}x{3}&maptype=roadmap&sensor=false".FormatInvariant(Uri.EscapeUriString(address), zoom, width, height));
    var href = new Uri("http://maps.google.com/maps?f=q&source=s_q&hl=en&q={0}".FormatInvariant(Uri.EscapeUriString(address)));

    var img = new TagBuilder("img");
    img.MergeAttribute("src", src.ToString());
    img.MergeAttribute("alt", alt);

    var link = new TagBuilder("a") { InnerHtml = img.ToString() };
    link.MergeAttribute("href", href.ToString());

    return MvcHtmlString.Create(link.ToString());
}

Для этого нового проекта мы также пытаемся сохранить все правила анализа кодана.Теперь, очевидно, анализ кода Visual Studio утверждает, что мы должны удалить параметр helper, потому что он не используется.

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

Есть ли у кого-нибудь ссылка на руководство или объяснение, которое поможет мне принять решение?

Ответы [ 3 ]

12 голосов
/ 24 сентября 2010

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

4 голосов
/ 24 сентября 2010

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

В таком случае я бы задал вопрос: «Имеет ли смысл рассматривать эту операцию над объектом HtmlHelper?». Это, в свою очередь, становится «имеет ли смысл рассматривать объекты HtmlHelper для выполнения этой операции?». Если бы я ответил «да» на этот вопрос, я бы счел целесообразным использовать метод расширения, независимо от того, использовал ли я объект HtmlHelper или нет. И наоборот, если бы я ответил «нет» на этот вопрос, я бы счел метод расширения опрометчивым, даже если объект HtmlHelper все-таки привык.

Анализ кода лучше выполняет анализ использования кода, чем концепции, поэтому здесь выдается предупреждение. Это несовершенно, и действительно есть другие случаи, когда игнорирование параметра является разумным (поддержание совместимости либо с предыдущей версией, либо с интерфейсом, являющимся наилучшим случаем, «зарезервированный для будущего использования», являющийся более спорным случаем).

Примечательно, что в некоторых языках (ну, C ++ для одного) вы можете не указывать имя параметра, чтобы оно означало «этот параметр есть в сигнатуре, но не будет использоваться». Мне это очень нравится, так как это правда, что вообще не использование параметра является плохим признаком, поэтому приятно иметь средство, чтобы указать, что вы были намерены в этом.

Edit:

Еще одно оправдание. Представьте, что у вас есть метод расширения для класса, который использует соответствующий объект. Теперь представьте, что вы понимаете, что можете сделать его более надежным, эффективным или иным образом «лучше» для некоторого значения «лучше», переписав таким образом, что вы больше не используете объект. Разве вам нельзя разрешить сохранить метод расширения теперь, когда вы его улучшили? Вы должны быть вынуждены остаться с нижней версией?

1 голос
/ 24 сентября 2010

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

...