Подтвердить что ты не робот

С# Дополнительные параметры или перегрузка метода?

Поскольку С# добавляет дополнительные параметры, считается, что лучше использовать необязательные параметры или перегрузки метода или есть частный случай, когда вы хотели бы использовать один над другим. то есть функция w/lots параметров будет лучше соответствовать w/необязательным параметрам?

4b9b3361

Ответ 1

Необязательные параметры хороши, но их следует использовать, когда это имеет смысл. Необязательные параметры часто замалчивают цель метода. Если есть другая альтернатива, я склоняюсь к альтернативе.

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

MSDN

Некоторые API, особенно COM-интерфейсы таких как API автоматизации Office, написаны специально с именованными и дополнительные параметры. вверх до сих пор было очень болезненно звоните в эти API из С#, с иногда до тридцати аргументов должны быть явно переданы, большинство из них разумные по умолчанию значения и могут быть опущены.

SomeNewKid из forums.asp.net помещает кратко:

http://forums.asp.net/t/386604.aspx/1

... перегруженные методы обычно предпочтительнее дополнительных параметров. Зачем? Чтобы сохранить каждый из ваших методов ясно. То есть каждый метод должен делать одно хорошо. Как только вы вводите дополнительные параметры, вы разбавляют чистоту этого метод и введение ветвления логики, которая, вероятно, лучше всего метода. Эта ясность цели становится еще более важным, когда вы начните использовать наследование. если ты переопределить метод, который имеет один или несколько необязательные параметры, они становятся с трудом работать. Итак, я бы предложил что для чего угодно, кроме быстрого и грязных классов, вы используете перегрузку в предпочтение к необязательным параметрам.

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

Отражатель С#:

public class Class1
{
    // Methods
    public Class1()
    {
        this.Method1("3", "23");
    }

    public void Method1(string one, [Optional, DefaultParameterValue("23")] string two)
    {
    }
}

IL

.class public auto ansi beforefieldinit Class1
    extends [mscorlib]System.Object
{
    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
        .maxstack 8
        L_0000: ldarg.0 
        L_0001: call instance void [mscorlib]System.Object::.ctor()
        L_0006: nop 
        L_0007: nop 
        L_0008: ldarg.0 
        L_0009: ldstr "3"
        L_000e: ldstr "23"
        L_0013: call instance void WebApplication1.Class1::Method1(string, string)
        L_0018: nop 
        L_0019: nop 
        L_001a: ret 
    }

    .method public hidebysig instance void Method1(string one, [opt] string two) cil managed
    {
        .param [2] = string('23')
        .maxstack 8
        L_0000: nop 
        L_0001: ret 
    }

}

Ответ 2

Анализ кода в Visual Studio и FxCop рекомендует использовать необязательные аргументы в публичных API (правило CA1026: параметры по умолчанию не должны использоваться). Причина в том, что не все языки .NET поддерживают их.

Я думаю, что лучшей причиной их избежать является то, что они могут вводить проблемы во время выполнения или компиляции, если вы добавите больше перегрузок в версии 2.0 вашего API. Фил Хаак объясняет здесь.

Я собираюсь принять заключение Фила: дополнительные параметры были разработаны для поддержки COM-взаимодействия; если вы не используете COM, оставьте их в покое.

Ответ 3

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

В частности, при работе с Intellisense я предпочитаю это видеть:

optional params with defaults

По этому поводу:

overload 1

overload 2

overload 3

Где мне, возможно, придется угадать (или искать документацию), для чего значение param1 и param2 будет, если я не укажу.

Ответ 4

Дополнительные параметры предназначены для облегчения взаимодействия объектов COM, поскольку объекты COM используют множество необязательных параметров. Поэтому, если вы делаете объекты P/Invoke или COM, предпочитаете необязательные параметры. В противном случае перегрузка метода - это правильный способ, так как это сэкономит много путаницы.

Ответ 5

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

Предполагая, что класс Bar имеет свойства публичной строки "Name" и "Pet", вы можете создать новый объект, подобный этому.

var foo = new Bar { Name = "Fred", Pet = "Dino" };

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

Ответ 6

Необязательные параметры требуют значения по умолчанию (я только предполагаю), и, следовательно, в некоторых случаях его может быть сложно предоставить. Зачем? Ну, некоторым классам требуется информация о времени выполнения для инициализации, которая может быть недоступна компилятору.

Когда дело доходит до примитивных типов, ответ может иметь отношение к случаю, если можно принять значение по умолчанию, или если отсутствие параметра может означать различное поведение с помощью метода.