문제

나는 읽었다 이 질문의 C++ 버전 하지만 실제로는 이해가 되지 않았습니다.

누군가가 그것이 가능한지, 어떻게 할 수 있는지 명확하게 설명해 주시겠습니까?

도움이 되었습니까?

해결책

사용 .NET 4.0+의 튜플:

예를 들어:

public Tuple<int, int> GetMultipleValue()
{
     return Tuple.Create(1,2);
}

두 값의 튜플이 있습니다 Item1 그리고 Item2 속성으로.

다른 팁

이제 C# 7이 출시되었으므로 새로운 포함 된 튜플 구문을 사용할 수 있습니다.

(string, string, string) LookupName(long id) // tuple return type
{
    ... // retrieve first, middle and last from data storage
    return (first, middle, last); // tuple literal
}

그런 다음 다음과 같이 사용할 수 있습니다.

var names = LookupName(id);
WriteLine($"found {names.Item1} {names.Item3}.");

당신은 또한 당신의 요소에 이름을 제공 할 수 있습니다 (따라서 "item1", "item2"등이 아닙니다). 서명 또는 반환 방법에 이름을 추가하여 수행 할 수 있습니다.

(string first, string middle, string last) LookupName(long id) // tuple elements have names

또는

return (first: first, middle: middle, last: last); // named tuple elements in a literal

그들은 또한 해체 될 수 있습니다. 이것은 아주 좋은 새로운 기능입니다.

(string first, string middle, string last) = LookupName(id1); // deconstructing declaration

체크 아웃 이 링크 할 수있는 일에 대한 더 많은 예를 보려면 :)

세 가지 방법을 사용할 수 있습니다

1. ref / out 매개 변수

REF 사용 :

static void Main(string[] args)
{
    int a = 10;
    int b = 20;
    int add = 0;
    int multiply = 0;
    Add_Multiply(a, b, ref add, ref multiply);
    Console.WriteLine(add);
    Console.WriteLine(multiply);
}

private static void Add_Multiply(int a, int b, ref int add, ref int multiply)
{
    add = a + b;
    multiply = a * b;
}

사용 :

static void Main(string[] args)
{
    int a = 10;
    int b = 20;
    int add;
    int multiply;
    Add_Multiply(a, b, out add, out multiply);
    Console.WriteLine(add);
    Console.WriteLine(multiply);
}

private static void Add_Multiply(int a, int b, out int add, out int multiply)
{
    add = a + b;
    multiply = a * b;
}

2. 구조 / 클래스

구조물 사용 :

struct Result
{
    public int add;
    public int multiply;
}
static void Main(string[] args)
{
    int a = 10;
    int b = 20;
    var result = Add_Multiply(a, b);
    Console.WriteLine(result.add);
    Console.WriteLine(result.multiply);
}

private static Result Add_Multiply(int a, int b)
{
    var result = new Result
    {
        add = a * b,
        multiply = a + b
    };
    return result;
}

수업 사용 :

class Result
{
    public int add;
    public int multiply;
}
static void Main(string[] args)
{
    int a = 10;
    int b = 20;
    var result = Add_Multiply(a, b);
    Console.WriteLine(result.add);
    Console.WriteLine(result.multiply);
}

private static Result Add_Multiply(int a, int b)
{
    var result = new Result
    {
        add = a * b,
        multiply = a + b
    };
    return result;
}

3. 튜플

튜플 클래스

static void Main(string[] args)
{
    int a = 10;
    int b = 20;
    var result = Add_Multiply(a, b);
    Console.WriteLine(result.Item1);
    Console.WriteLine(result.Item2);
}

private static Tuple<int, int> Add_Multiply(int a, int b)
{
    var tuple = new Tuple<int, int>(a + b, a * b);
    return tuple;
}

C# 7 튜플

static void Main(string[] args)
{
    int a = 10;
    int b = 20;
    (int a_plus_b, int a_mult_b) = Add_Multiply(a, b);
    Console.WriteLine(a_plus_b);
    Console.WriteLine(a_mult_b);
}

private static (int a_plus_b, int a_mult_b) Add_Multiply(int a, int b)
{
    return(a + b, a * b);
}

C#에서는 이것을 할 수 없습니다. 당신이 할 수있는 일은 a입니다 out 매개 변수 또는 자신의 클래스를 반환합니다 (또는 불변이없는 경우 구조물).

아웃 매개 변수 사용
public int GetDay(DateTime date, out string name)
{
  // ...
}
사용자 정의 클래스 사용 (또는 구조물)
public DayOfWeek GetDay(DateTime date)
{
  // ...
}

public class DayOfWeek
{
  public int Day { get; set; }
  public string Name { get; set; }
}

여러 값을 반환한다는 의미이라면 반환하려는 값이 포함 된 클래스/구조물을 반환하거나 매개 변수에서 "Out"키워드를 사용하여 다음과 같습니다.

public void Foo(int input, out int output1, out string output2, out string errors) {
    // set out parameters inside function
}

이전 포스터가 맞습니다. C# 메소드에서 여러 값을 반환 할 수 없습니다. 그러나 몇 가지 옵션이 있습니다.

  • 여러 회원이 포함 된 구조를 반환하십시오
  • 클래스 인스턴스를 반환하십시오
  • 출력 매개 변수를 사용하십시오 (사용 밖으로 또는 심판 키워드)
  • 사전 또는 키 값 쌍을 출력으로 사용하십시오

여기서 장단점은 종종 알아 내기가 어렵습니다. 구조를 반환하면 구조물이 가치 유형이고 스택에 전달되므로 구조가 작아 지도록하십시오. 클래스 인스턴스를 반환하는 경우 문제를 일으키지 않기 위해 사용할 수있는 몇 가지 설계 패턴이 있습니다. C#이 객체를 참조하여 통과하기 때문에 클래스의 구성원을 수정할 수 있습니다 (VB에서했던 것처럼 ByVal이 없습니다. ).

마지막으로 출력 매개 변수를 사용할 수는 있지만 커플 (3 이하)의 매개 변수 만있을 때이 사용을 시나리오로 제한합니다. 그렇지 않으면 상황이 못 생겼고 유지하기가 어려워집니다. 또한, 출력 매개 변수를 사용하는 것은 원인에 대한 억제제가 될 수 있습니다. 왜냐하면 메소드 서명은 반환 값에 무언가를 추가해야 할 때마다 변경 해야하는 반면, 구조물 또는 클래스 인스턴스를 반환하면 메소드 서명을 수정하지 않고 멤버를 추가 할 수 있습니다.

건축 적 관점에서 키 값 쌍 또는 사전을 사용하는 것을 권장합니다. 이 스타일의 코딩에는 방법을 소비하는 코드에 "비밀 지식"이 필요하다는 것을 알게됩니다. 키가 무엇인지, 값의 의미와 내부 구현에서 작업하는 개발자가 사전 또는 KVP가 생성되는 방식을 변경하면 전체 애플리케이션에서 실패 캐스케이드를 쉽게 만들 수 있습니다.

당신은 a 수업 인스턴스 또는 사용 밖으로 매개 변수. 다음은 아웃 매개 변수의 예입니다.

void mymethod(out int param1, out int param2)
{
    param1 = 10;
    param2 = 20;
}

다음과 같이 부릅니다.

int i, j;
mymethod(out i, out j);
// i will be 20 and j will be 10

이를 수행하는 방법에는 여러 가지가 있습니다. 당신이 사용할 수있는 ref 매개 변수 :

int Foo(ref Bar bar) { }

이렇게하면 함수에 대한 참조가 전달되어 함수가 호출 코드 스택에서 객체를 수정할 수 있습니다. 기술적으로 "반환 된"값은 아니지만 기능이 비슷한 일을하도록하는 방법입니다. 위의 코드에서 함수는 an을 반환합니다 int (잠재적으로) 수정 bar.

또 다른 유사한 접근법은 An을 사용하는 것입니다 out 매개 변수. an out 매개 변수는 a와 동일합니다 ref 추가 컴파일러 시행 규칙이있는 매개 변수. 이 규칙은 당신이 통과하는 경우입니다 out 함수로 매개 변수로, 해당 함수는 반환 전에 값을 설정하려면 필요합니다. 그 규칙 외에도 out 매개 변수는 a처럼 작동합니다 ref 매개 변수.

최종 접근법 (및 대부분의 경우 가장 좋은 방법)은 두 값을 모두 캡슐화하고 함수가 다음을 반환하도록하는 유형을 작성하는 것입니다.

class FooBar 
{
    public int i { get; set; }
    public Bar b { get; set; }
}

FooBar Foo(Bar bar) { }

이 최종 접근 방식은 더 간단하고 읽고 이해하기 쉽습니다.

아니요, C#의 함수 (C# 7보다 낮은 버전의 경우)에서 여러 값을 반환 할 수는 없습니다. 적어도 Python에서 수행 할 수있는 방식은 아닙니다.

그러나 몇 가지 대안이 있습니다.

원하는 다중 값으로 유형 객체 배열을 반환 할 수 있습니다.

private object[] DoSomething()
{
    return new [] { 'value1', 'value2', 3 };
}

당신이 사용할 수있는 out 매개 변수.

private string DoSomething(out string outparam1, out int outparam2)
{
    outparam1 = 'value2';
    outparam2 = 3;
    return 'value1';
}

C# 4에서는 튜플에 대한 기본 지원을 사용하여 이를 쉽게 처리할 수 있습니다.

그동안 두 가지 옵션이 있습니다.

먼저, ref 또는 out 매개변수를 사용하여 매개변수에 값을 할당할 수 있으며, 이 값은 호출 루틴으로 다시 전달됩니다.

이것은 다음과 같습니다:

void myFunction(ref int setMe, out int youMustSetMe);

둘째, 반환 값을 구조체나 클래스로 마무리하고 해당 구조체의 멤버로 다시 전달할 수 있습니다.KeyValuePair는 2개에 적합합니다. 2개 이상인 경우에는 사용자 정의 클래스 또는 구조체가 필요합니다.

C#7에는 새로운 것이 있습니다 Tuple 통사론:

static (string foo, int bar) GetTuple()
{
    return ("hello", 5);
}

이것을 레코드로 반환 할 수 있습니다.

var result = GetTuple();
var foo = result.foo
// foo == "hello"

새로운 디 구성원 구문을 사용할 수도 있습니다.

(string foo) = GetTuple();
// foo == "hello"

그러나 직렬화에주의를 기울여야합니다. 그러나이 모든 것은 구문 설탕입니다. 실제 컴파일 된 코드에서는 이것이 Tupel<string, int> (처럼 허용 된 답변에 따라) 와 함께 Item1 그리고 Item2 대신에 foo 그리고 bar. 즉, 직렬화 (또는 사제화)는 해당 속성 이름을 대신 사용한다는 것을 의미합니다.

따라서 직렬화를 위해 레코드 클래스를 선언하고 대신 반환합니다.

또한 C#7의 새로운 새로운 구문입니다. out 매개 변수. 이제 선언 할 수 있습니다 out 인라인, 일부 상황에서 더 적합합니다.

if(int.TryParse("123", out int result)) {
    // Do something with result
}

그러나 대부분 자신의 기능보다는 .NET 자체 라이브러리에서 이것을 사용할 것입니다.

일부 답변은 사용을 제안합니다 아웃 매개 변수 그러나 나는 이것을 사용하지 않는 것이 좋습니다 그들은 비동기 방법으로 작동하지 않습니다. 보다 이것 자세한 내용은.

다른 답변은 튜플을 사용하여 언급했지만 C# 7.0에 도입 된 새로운 기능을 사용하는 것이 좋습니다.

(string, string, string) LookupName(long id) // tuple return type
{
    ... // retrieve first, middle and last from data storage
    return (first, middle, last); // tuple literal
}

var names = LookupName(id);
WriteLine($"found {names.Item1} {names.Item3}.");

추가 정보를 찾을 수 있습니다 여기.

이 "keyvaluepair"를 시도해 볼 수 있습니다.

private KeyValuePair<int, int> GetNumbers()
{
  return new KeyValuePair<int, int>(1, 2);
}


var numbers = GetNumbers();

Console.WriteLine("Output : {0}, {1}",numbers.Key, numbers.Value);

출력 :

출력 : 1, 2

클래스, 구조, 컬렉션 및 배열에는 여러 값이 포함될 수 있습니다. 출력 및 참조 매개 변수도 함수에서 설정할 수 있습니다. 리턴 다중 값은 튜플을 통해 동적 및 기능적 언어로 가능하지만 C#에서는 가능하지 않습니다.

주로 두 가지 방법이 있습니다. 1. out/ref 매개 변수 사용 2. 객체 배열을 반환합니다.

다음은 기본입니다 Two 행동 양식:

1) '사용'out'매개 변수로4.0 및 마이너 버전 모두에 '아웃'을 사용할 수 있습니다.

'out'의 예 :

using System;

namespace out_parameter
{
  class Program
   {
     //Accept two input parameter and returns two out value
     public static void rect(int len, int width, out int area, out int perimeter)
      {
        area = len * width;
        perimeter = 2 * (len + width);
      }
     static void Main(string[] args)
      {
        int area, perimeter;
        // passing two parameter and getting two returning value
        Program.rect(5, 4, out area, out perimeter);
        Console.WriteLine("Area of Rectangle is {0}\t",area);
        Console.WriteLine("Perimeter of Rectangle is {0}\t", perimeter);
        Console.ReadLine();
      }
   }
}

산출:

직사각형 영역은 20입니다

직사각형의 주변은 18입니다

*메모:*그만큼 out-keyword는 실제 변수 위치가 호출 된 메소드의 스택에 복사되는 매개 변수를 설명합니다. 여기서 동일한 위치를 다시 작성할 수 있습니다. 이는 호출 방법이 변경된 매개 변수에 액세스한다는 것을 의미합니다.

2) Tuple<T>

튜플의 예 :

여러 데이터 유형 값을 사용하여 반환합니다 Tuple<T>

using System;

class Program
{
    static void Main()
    {
    // Create four-item tuple; use var implicit type.
    var tuple = new Tuple<string, string[], int, int[]>("perl",
        new string[] { "java", "c#" },
        1,
        new int[] { 2, 3 });
    // Pass tuple as argument.
    M(tuple);
    }

    static void M(Tuple<string, string[], int, int[]> tuple)
    {
    // Evaluate the tuple's items.
    Console.WriteLine(tuple.Item1);
    foreach (string value in tuple.Item2)
    {
        Console.WriteLine(value);
    }
    Console.WriteLine(tuple.Item3);
    foreach (int value in tuple.Item4)
    {
        Console.WriteLine(value);
    }
    }
}

산출

perl
java
c#
1
2
3

노트: 튜플 사용은 프레임 워크 4.0 이상에서 유효합니다..Tuple 유형은 a입니다 class. 메모리의 관리 된 힙의 별도 위치에 할당됩니다. 일단 당신이 만들어지면 Tuple, 당신은 그것의 값을 변경할 수 없습니다 fields. 이것은로 만듭니다 Tuple 더 a struct.

대의원을 취하는 방법은 발신자에게 여러 값을 제공 할 수 있습니다. 이것은 내 대답에서 빌린다 여기 조금만 사용합니다 Hadas의 인정 된 답변.

delegate void ValuesDelegate(int upVotes, int comments);
void GetMultipleValues(ValuesDelegate callback)
{
    callback(1, 2);
}

발신자는 Lambda (또는 명명 된 기능)를 제공하고 Intellisense는 대의원에서 변수 이름을 복사하여 도움을줍니다.

GetMultipleValues((upVotes, comments) =>
{
     Console.WriteLine($"This post has {upVotes} Up Votes and {comments} Comments.");
});

다음과 같은 클래스를 OOP 방식으로 사용하십시오.

class div
{
    public int remainder;

    public int quotient(int dividend, int divisor)
    {
        remainder = ...;
        return ...;
    }
}

함수 멤버는 대부분의 발신자가 주로 관심을 갖는 몫을 반환합니다. 또한 나머지는 데이터 구성원으로 저장하여 발신자가 쉽게 액세스 할 수 있습니다.

이러한 방식으로 많은 오류 메시지가 필요한 경우에만 데이터베이스 또는 네트워킹 호출을 구현하는 경우 매우 유용한 추가 "반환 값"을 가질 수 있습니다.

OP가 언급하는 C ++ 질문 에서도이 솔루션을 입력했습니다.

에서 이것 기사, 위의 게시물과 같이 세 가지 옵션을 사용할 수 있습니다.

keyvaluepair 가장 빠른 방법입니다.

밖으로 두 번째입니다.

튜플 가장 느린 것입니다.

어쨌든 이것은 시나리오에 가장 적합한 것이 무엇인지에 따라 다릅니다.

C#의 향후 버전에는 명명 된 튜플이 포함됩니다. 데모에 대한이 Channel9 세션을 살펴보십시오.https://channel9.msdn.com/events/build/2016/B889

튜플 물건을 위해 13:00으로 건너 뛰십시오. 이것은 다음과 같은 것들을 허용합니다.

(int sum, int count) Tally(IEnumerable<int> list)
{
// calculate stuff here
return (0,0)
}

int resultsum = Tally(numbers).sum

(비디오에서 불완전한 예)

동적 객체를 사용할 수 있습니다. 나는 그것이 튜플보다 더 나은 가독성을 가지고 있다고 생각합니다.

static void Main(string[] args){
    var obj = GetMultipleValues();
    Console.WriteLine(obj.Id);
    Console.WriteLine(obj.Name);
}

private static dynamic GetMultipleValues() {
    dynamic temp = new System.Dynamic.ExpandoObject();
    temp.Id = 123;
    temp.Name = "Lorem Ipsum";
    return temp;
}
<--Return more statements like this you can --> 

public (int,string,etc) Sample( int a, int b)  
{
    //your code;
    return (a,b);  
}

당신은 같은 코드를받을 수 있습니다

(c,d,etc) = Sample( 1,2);

작동하기를 바랍니다.

이를 수행하는 방법 :

1) keyvaluepair (최고의 성능 -0.32 ns) :

    KeyValuePair<int, int> Location(int p_1, int p_2, int p_3, int p_4)
    {                 
         return new KeyValuePair<int,int>(p_2 - p_1, p_4-p_3);
    }

2) 튜플 -5.40 ns :

    Tuple<int, int> Location(int p_1, int p_2, int p_3, int p_4)
    {
          return new Tuple<int, int>(p_2 - p_1, p_4-p_3);
    }

3) out (1.64 ns) 또는 Ref 4) 자신의 사용자 정의 클래스/구조물 만들기

NS-> 나노 초

참조: 다중 리턴 값.

당신은 이것을 시도 할 수 있습니다

public IEnumerable<string> Get()
 {
     return new string[] { "value1", "value2" };
 }

OperationResult를 사용할 수도 있습니다

public OperationResult DoesSomething(int number1, int number2)
{
// Your Code
var returnValue1 = "return Value 1";
var returnValue2 = "return Value 2";

var operationResult = new OperationResult(returnValue1, returnValue2);
return operationResult;
}

여러 가지 방법이 있습니다. 그러나 새 객체 나 구조 또는 이와 같은 것을 만들고 싶지 않다면 아래에서 아래에서 할 수 있습니다. C# 7.0 :

 (string firstName, string lastName) GetName(string myParameter)
    {
        var firstName = myParameter;
        var lastName = myParameter + " something";
        return (firstName, lastName);
    }

    void DoSomethingWithNames()
    {
        var (firstName, lastName) = GetName("myname");

    }

오늘날 프로그래머는 시간과 용서할 수없는 방법이 필요합니다. 간단하고 일하고 빠른 솔루션 :

private int[] SumAndSub(int A, int B)
{
    return new[] { A + B , A - B };
}

어딘가에서 사용;

var results = SumAndSub(20, 5);
int sum = results[0];
int sub = results[0];
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top