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

Как использовать необязательные параметры в С#?

Примечание. Этот вопрос задавался в то время, когда С# еще не поддерживал необязательные параметры (то есть до С# 4).

Мы создаем веб-API, программно созданный из класса С#. Класс имеет метод GetFooBar(int a, int b), и API имеет метод GetFooBar, имеющий параметры запроса, такие как &a=foo &b=bar.

Классы должны поддерживать необязательные параметры, которые не поддерживаются на языке С#. Какой лучший подход?

4b9b3361

Ответ 1

Удивленный никто не упоминал дополнительные параметры С# 4.0, которые работают следующим образом:

public void SomeMethod(int a, int b = 0)
{
   //some code
}

Изменить: Я знаю, что в то время, когда задавался вопрос, С# 4.0 не существовал. Но этот вопрос по-прежнему занимает №1 в Google для "дополнительных аргументов С#", поэтому я подумал - этот ответ стоит здесь. К сожалению.

Ответ 2

Другой вариант - использовать ключевое слово params

public void DoSomething(params object[] theObjects)
{
  foreach(object o in theObjects)
  {
    // Something with the Objects…
  }
}

Вызывается как...

DoSomething(this, that, theOther);

Ответ 3

В С# я обычно использовал бы несколько форм метода:

void GetFooBar(int a) { int defaultBValue;  GetFooBar(a, defaultBValue); }
void GetFooBar(int a, int b)
{
 // whatever here
}

UPDATE:. Это упомянутое выше было способом, которым я использовал значения по умолчанию с С# 2.0. Проекты, над которыми я сейчас работаю, используют С# 4.0, который теперь напрямую поддерживает дополнительные параметры. Вот пример, который я использовал только в своем собственном коде:

public EDIDocument ApplyEDIEnvelop(EDIVanInfo sender, 
                                   EDIVanInfo receiver, 
                                   EDIDocumentInfo info,
                                   EDIDocumentType type 
                                     = new EDIDocumentType(EDIDocTypes.X12_814),
                                   bool Production = false)
{
   // My code is here
}

Ответ 4

С этого сайта:

http://www.tek-tips.com/viewthread.cfm?qid=1500861&page=1

С# позволяет использовать атрибут [Необязательный] (из VB, хотя и не работает на С#). Поэтому у вас может быть такой метод:

using System.Runtime.InteropServices;
public void Foo(int a, int b, [Optional] int c)
{
  ...
}

В нашей API-оболочке мы обнаруживаем необязательные параметры (ParameterInfo p.IsOptional) и устанавливаем значение по умолчанию. Цель состоит в том, чтобы пометить параметры как необязательные, не прибегая к клокам, например, "необязательно" в имени параметра.

Ответ 5

Вы можете использовать перегрузку метода...

GetFooBar()
GetFooBar(int a)
GetFooBar(int a, int b)

Это зависит от сигнатур метода, в приведенном примере отсутствует метод "int b", поскольку он будет иметь такую ​​же подпись, что и метод "int a".

Вы можете использовать типы Nullable...

GetFooBar(int? a, int? b)

Затем вы можете проверить, используя a.HasValue, чтобы узнать, был ли установлен параметр.

Другой вариант - использовать параметр params.

GetFooBar(params object[] args)

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

Ответ 6

Вы можете использовать необязательные параметры в С# 4.0 без каких-либо проблем. Если у нас есть метод вроде:

int MyMetod(int param1, int param2, int param3=10, int param4=20){....}

когда вы вызываете метод, вы можете пропустить такие параметры:

int variab = MyMethod(param3:50; param1:10);

С# 4.0 реализует функцию под названием "именованные параметры", вы можете передавать параметры по их именам, и, конечно же, вы можете передавать параметры в любом порядке:

Ответ 7

Hello Необязательный мир

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

using System;
using System.Runtime.InteropServices;
using System.Reflection;

namespace ConsoleApplication1
{
    class Class1
    {
        public static void sayHelloTo(
            [Optional,
            DefaultParameterValue("world")] string whom)
        {
            Console.WriteLine("Hello " + whom);
        }

        [STAThread]
        static void Main(string[] args)
        {
            MethodInfo mi = typeof(Class1).GetMethod("sayHelloTo");
            mi.Invoke(null, new Object[] { Missing.Value });
        }
    }
}

Ответ 8

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

public void PrintValues(int? a = null, int? b = null, float? c = null, string s = "")
{
    if(a.HasValue)
        Console.Write(a);
    else
        Console.Write("-");

    if(b.HasValue)
        Console.Write(b);
    else
        Console.Write("-");

    if(c.HasValue)
        Console.Write(c);
    else
        Console.Write("-");

    if(string.IsNullOrEmpty(s)) // Different check for strings
        Console.Write(s);
    else
        Console.Write("-");
}

Строки уже обнуляются, поэтому они не нужны ? ,

Если у вас есть этот метод, все следующие вызовы действительны:

PrintValues (1, 2, 2.2f);
PrintValues (1, c: 1.2f);
PrintValues(b:100);
PrintValues (c: 1.2f, s: "hello");
PrintValues();

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

Именованные и необязательные аргументы (Руководство по программированию в С#) @MSDN

Ответ 9

Я согласен с stephenbayer. Но поскольку это веб-сервис, конечным пользователям проще использовать только одну форму веб-метода, чем использовать несколько версий одного и того же метода. Я думаю, что в этой ситуации Nullable Types идеально подходят для дополнительных параметров.

public void Foo(int a, int b, int? c)
{
  if(c.HasValue)
  {
    // do something with a,b and c
  }
  else
  {
    // do something with a and b only
  }  
}

Ответ 10

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

  • с помощью С# 4.0: используйте необязательные аргументы в конструкторе класса, решение, которое я предпочитаю, поскольку оно ближе к тому, что делается с помощью методов, поэтому его легче запомнить. вот пример:

    class myClass
    {
        public myClass(int myInt = 1, string myString =
                               "wow, this is cool: i can have a default string")
        {
            // do something here if needed
        }
    }
    
  • с использованием версий С#, предшествующих С# 4.0: вы должны использовать цепочку конструкторов (используя это: это ключевое слово), где более простые конструкторы приводят к "мастер-конструктору". Пример:

    class myClass
    {
        public myClass()
        {
        // this is the default constructor
        }
    
        public myClass(int myInt)
            : this(myInt, "whatever")
        {
            // do something here if needed
        }
        public myClass(string myString)
            : this(0, myString)
        {
            // do something here if needed
        }
        public myClass(int myInt, string myString)
        {
            // do something here if needed - this is the master constructor
        }
    }
    

Ответ 11

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

Ответ 12

Вы можете перегрузить ваш метод. Один метод содержит один параметр GetFooBar(int a), а другой содержит оба параметра, GetFooBar(int a, int b)

Ответ 13

Использование перегрузок или использование С# 4.0 или выше

 private void GetVal(string sName, int sRoll)
 {
   if (sRoll > 0)
   {
    // do some work
   }
 }

 private void GetVal(string sName)
 {
    GetVal("testing", 0);
 }

Ответ 14

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

то есть. Request.QueryString [ "a" ]

Это отделит класс листа от factory/шаблонного кода.


Вы также можете проверить Веб-службы с ASP.NET. Веб-сервисы - это веб-api, сгенерированные автоматически через атрибуты на классах С#.

Ответ 15

Немного опоздал на вечеринку, но я искал ответ на этот вопрос и в конце концов выяснил еще один способ сделать это. Объявить типы данных для дополнительных аргументов вашего веб-метода как типа XmlNode. Если опционный аргумент arg опущен, он будет установлен в значение null, и если он присутствует, вы можете получить строковое значение, вызвав arg.Value, i.e.,

[WebMethod]
public string Foo(string arg1, XmlNode optarg2)
{
    string arg2 = "";
    if (optarg2 != null)
    {
        arg2 = optarg2.Value;
    }
    ... etc
}

То, что также подходит для этого подхода, - это домашняя страница с .NET, созданная для ws, по-прежнему показывает список аргументов (хотя вы теряете удобные текстовые поля для тестирования).

Ответ 16

У меня есть веб-сервис для записи, который принимает 7 параметров. Каждый из них является необязательным атрибутом запроса для оператора sql, заверенного этим веб-сервисом. Поэтому приходят два обходных пути к необязательным параметрам... оба довольно бедные:

method1 (param1, param2, param 3, param 4, param 5, param 6, param7) method1 (param1, param2, param3, param 4, param5, param 6) метод 1 (param1, param2, param3, param4, param5, param7)... начните видеть изображение. Этот путь - безумие. Путь слишком много комбинаций.

Теперь для более простого способа, который выглядит неудобно, но должен работать: method1 (param1, bool useParam1, param2, bool useParam2 и т.д.)

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

Это взломать, но он будет работать.

Ответ 17

Я должен был сделать это в веб-службе VB.Net 2.0. Я закончил указывать параметры как строки, а затем преобразовал их в то, что мне нужно. Необязательный параметр был задан пустой строкой. Не самое чистое решение, но оно сработало. Просто будьте осторожны, чтобы уловить все исключения, которые могут произойти.

Ответ 18

На всякий случай, если кто-то хочет передать обратный вызов (или delegate) в качестве необязательного параметра, может сделать это таким образом.

Дополнительный параметр обратного вызова:

public static bool IsOnlyOneElement(this IList lst, Action callbackOnTrue = (Action)((null)), Action callbackOnFalse = (Action)((null)))
{
    var isOnlyOne = lst.Count == 1;
    if (isOnlyOne && callbackOnTrue != null) callbackOnTrue();
    if (!isOnlyOne && callbackOnFalse != null) callbackOnFalse();
    return isOnlyOne;
}

Ответ 19

необязательные параметры - не что иное, как параметры по умолчанию! Я предлагаю вам дать оба параметра по умолчанию. GetFooBar (int a = 0, int b = 0), если у вас нет перегруженного метода, приведет к a = 0, b = 0, если вы не передадите никаких значений, если вы передадите 1 значение, приведет к, переданное значение для a, 0 и если вы передадите 2 значения, 1-е будет присвоено a, а второе - b.

Надеюсь это ответит на твой вопрос.

Ответ 20

Если значения по умолчанию недоступны, можно добавить необязательный параметр, используя класс .NET OptionalAttribute - https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.optionalattribute?view=netframework-4.8

Пример кода ниже:

namespace OptionalParameterWithOptionalAttribute
{
    class Program
    {
        static void Main(string[] args)
        {
            //Calling the helper method Hello only with required parameters
            Hello("Vardenis", "Pavardenis");
            //Calling the helper method Hello with required and optional parameters
            Hello("Vardenis", "Pavardenis", "Palanga");
        }
        public static void Hello(string firstName, string secondName, 
            [System.Runtime.InteropServices.OptionalAttribute] string  fromCity)
        {
            string result = firstName + " " + secondName;
            if (fromCity != null)
            {
                result += " from " + fromCity;
            }
            Console.WriteLine("Hello " + result);
        }

    }
}

Ответ 21

Вы можете попробовать это тоже
Тип 1
public void YourMethod(int a=0, int b = 0) {//some code }


Тип 2
public void YourMethod(int? a, int? b) {//some code }