คืนค่าหลายค่าไปยังผู้เรียกเมธอด


คำตอบ:


609

ใน C # 7 ขึ้นไปดูคำตอบนี้

ในเวอร์ชันก่อนหน้าคุณสามารถใช้. NET 4.0 + ของ Tuple :

ตัวอย่างเช่น:

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

สิ่งอันดับที่มีสองค่ามีItem1และItem2เป็นคุณสมบัติ


8
มันจะดีมากถ้าแทน Item1, Item2 และอย่างใดอย่างหนึ่งสามารถใช้ค่าผลลัพธ์ที่มีชื่อ C # 7 อาจจะเป็นไปเพื่อให้ได้ว่า
Sнаđошƒаӽ

1
@ Sнаđошƒаӽขวาเป็นอย่างนี้คาดว่าจะได้รับการสนับสนุนใน C # 7.0 ที่จะเกิดขึ้นโดยใช้ไวยากรณ์เช่น: public (int sum, int count) GetMultipleValues() { return (1, 2); }ตัวอย่างนี้ถูกนำมาจากตัวอย่างหัวข้อเอกสารของเราเกี่ยวกับเรื่องนี้
Jeppe Stig Nielsen

435

เมื่อ C # 7 เปิดตัวแล้วคุณสามารถใช้ไวยากรณ์ Tuples ที่รวมมาใหม่ได้

(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

ลองดูลิงค์นี้เพื่อดูตัวอย่างเพิ่มเติมเกี่ยวกับสิ่งที่สามารถทำได้ :)


11
หากคุณกำหนดเป้าหมายอะไรก่อนหน้านี้กว่า .NET Framework 4.7 หรือ 2.0 .NET หลักคุณจะต้องติดตั้งแพคเกจ NuGet
Phil

1
เพื่อให้ได้ผลตอบแทนคุณสามารถทำได้: "var result = LookupName (5); Console.WriteLine (result.middle)"
alansiqueira27

204

คุณสามารถใช้สามวิธีที่แตกต่างกัน

1. พารามิเตอร์อ้างอิง / ออก

ใช้การอ้างอิง:

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:

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. Tuple

ระดับ Tuple

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;
}

สิ่งอันดับ # 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);
}

3
แค่เพื่อความเป็นตัวของฉันเองคุณจะพูดว่าเร็วและ 'แนวปฏิบัติที่ดีที่สุด'?
Netferret

ตัวอย่างที่ดีที่สุดสำหรับ 'using struct' :)
SHEKHAR SHETE

1
แนะนำให้เพิ่มไวยากรณ์ c # 7 (และมีคนโหวตเพิ่มอีก :))
twomm

สำหรับข้อมูลของคุณพิมพ์ผิดขนาดเล็ก (ไม่เกี่ยวข้อง): ในการแก้ปัญหา struct / class คุณผสมการเพิ่ม / การคูณ
Szak1

ฉันไม่ทราบว่าไวยากรณ์ C # Tuple เป็นอะไร! เรียนรู้สิ่งใหม่หลังจากหลายปี!
jhaagsma

75

คุณไม่สามารถทำได้ใน C # สิ่งที่คุณสามารถทำได้คือมีoutพารามิเตอร์หรือส่งคืนคลาสของคุณเอง (หรือ struct หากคุณต้องการให้ไม่เปลี่ยนรูป)

การใช้พารามิเตอร์
public int GetDay(DateTime date, out string name)
{
  // ...
}
การใช้คลาสที่กำหนดเอง (หรือ struct)
public DayOfWeek GetDay(DateTime date)
{
  // ...
}

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

24
ทางเลือกในกรณีนี้คือการใช้โครงสร้างแทนคลาสสำหรับประเภทส่งคืน ถ้าค่าส่งคืนเป็นไร้รัฐและชั่วคราว struct เป็นตัวเลือกที่ดีกว่า
ไมเคิลเมโดวส์

1
นี้เป็นไปไม่ได้กับasyncวิธีการ Tupleเป็นวิธีที่จะไป (ผมใช้outพารามิเตอร์ในการดำเนินการซิงโครแม้ว่าพวกเขาจะมีประโยชน์ในกรณีดังกล่าวแน่นอน.)
Codefun64

5
ตอนนี้เป็นไปได้ใน C # 7: (int, int) วิธี () {return (1, 2); }
Spook

4
คำตอบต้องได้รับการอัปเดตมันผิดปกติกับ c # รุ่นล่าสุด จะเปลี่ยน downvote เป็น upvote หากอัปเดต
whitneyland

การทำงานบนฐานรหัสดั้งเดิมการส่งคืนคลาสที่กำหนดเองเป็นวิธีที่ดีสำหรับฉัน
ตัวผู้

38

หากคุณหมายถึงการคืนค่าหลายค่าคุณสามารถส่งคืนคลาส / โครงสร้างที่มีค่าที่คุณต้องการส่งคืนหรือใช้คำหลัก "ออก" ในพารามิเตอร์ของคุณเช่น:

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

2
ฉันไม่คิดว่ามันดีที่จะใช้ "out" หรือ "ref" —— เพราะมันสามารถทดแทนได้ทั้งหมดโดยคืนค่าของประเภทคลาสของคุณเอง คุณเห็นถ้าใช้ "ref" จะกำหนดให้พารามิเตอร์อย่างไร (ขึ้นอยู่กับวิธีการใช้โค้ดด้านใน) หากอยู่ในเนื้อความของฟังก์ชันผู้แต่งมี "newed" อินสแตนซ์ไปยังพารามิเตอร์ด้วย "ref" ซึ่งหมายความว่าคุณสามารถส่งค่า "nullable" ได้ที่นั่น ไม่ต้องการสิ่งอื่น นั่นเป็นความคลุมเครือเล็กน้อย และเรามีวิธีที่ดีกว่า (1. การส่งคืนคลาสที่คุณเป็นเจ้าของ 2. Turple)

33

โปสเตอร์ก่อนหน้านี้ถูกต้อง คุณไม่สามารถคืนค่าหลายค่าจากวิธี C # อย่างไรก็ตามคุณมีตัวเลือกสองทาง:

  • ส่งคืนโครงสร้างที่มีสมาชิกหลายคน
  • ส่งคืนอินสแตนซ์ของคลาส
  • ใช้พารามิเตอร์เอาต์พุต (ใช้คำหลักoutหรือref )
  • ใช้คู่พจนานุกรมหรือคีย์ - ค่าเป็นเอาต์พุต

ข้อดีและข้อเสียที่นี่มักจะยากที่จะคิดออก ถ้าคุณคืนค่าโครงสร้างตรวจสอบให้แน่ใจว่ามันมีขนาดเล็กเพราะ structs เป็นประเภทค่าและส่งผ่านไปยังสแต็ก หากคุณส่งคืนอินสแตนซ์ของคลาสมีรูปแบบการออกแบบบางส่วนที่นี่ที่คุณอาจต้องการใช้เพื่อหลีกเลี่ยงปัญหา - สมาชิกของคลาสสามารถแก้ไขได้เนื่องจาก C # ส่งผ่านวัตถุโดยการอ้างอิง (คุณไม่มี ByVal เหมือนที่คุณทำใน VB )

ในที่สุดคุณสามารถใช้พารามิเตอร์เอาต์พุต แต่ฉันจะ จำกัด การใช้สิ่งนี้กับสถานการณ์เมื่อคุณมีเพียงไม่กี่พารามิเตอร์ (เช่น 3 หรือน้อยกว่า) - ไม่อย่างนั้นสิ่งต่าง ๆ น่าเกลียดและยากที่จะรักษา นอกจากนี้การใช้พารามิเตอร์เอาต์พุตอาจเป็นตัวยับยั้งความคล่องตัวเนื่องจากลายเซ็นวิธีการของคุณจะต้องเปลี่ยนทุกครั้งที่คุณต้องการเพิ่มบางสิ่งบางอย่างในค่าส่งคืนในขณะที่ส่งคืนโครงสร้างหรืออินสแตนซ์คลาสคุณสามารถเพิ่มสมาชิกโดยไม่ต้องแก้ไข

จากมุมมองทางสถาปัตยกรรมฉันขอแนะนำให้ใช้คู่หรือคีย์ - ค่าพจนานุกรม ฉันพบว่ารูปแบบการเข้ารหัสนี้ต้องการ "ความรู้ลับ" ในรหัสที่ใช้วิธีนี้ ต้องทราบล่วงหน้าว่ากุญแจจะเป็นอย่างไรและคุณค่าหมายถึงอะไรและหากนักพัฒนาที่ทำงานเกี่ยวกับการใช้งานภายในเปลี่ยนแปลงวิธีการสร้างพจนานุกรมหรือ KVP มันจะสามารถสร้างความล้มเหลวได้อย่างง่ายดายตลอดทั้งแอปพลิเคชัน


และคุณยังสามารถโยนExceptionถ้าค่าที่สองที่คุณต้องการคืนนั้นแยกออกจากค่าแรก: เช่นเมื่อคุณต้องการคืนค่าที่ประสบความสำเร็จหรือมูลค่าที่ไม่ประสบความสำเร็จ
C Junur

21

คุณจะกลับมาเป็นเช่นชั้นหรือใช้ออกพารามิเตอร์ นี่คือตัวอย่างของพารามิเตอร์ out:

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

3
จำไว้ว่าเพียงเพราะคุณทำได้ แต่ไม่ได้หมายความว่าคุณควรทำเช่นนี้ สิ่งนี้ได้รับการยอมรับอย่างกว้างขวางว่าเป็นวิธีปฏิบัติที่ไม่ดีใน. Net ในกรณีส่วนใหญ่
ไมเคิลเมโดวส์

4
คุณช่วยอธิบายได้ไหมว่าทำไมนี่ถึงเป็นการปฏิบัติที่ไม่ดี?
Zo มี

มันเป็นวิธีปฏิบัติที่ไม่ดีใน C / C ++ ปัญหาคือ "การเขียนโปรแกรมโดยผลข้างเคียง": int GetLength (char * s) {int n = 0; ในขณะที่ (s [n]! = '\ 0') n ++; s [1] = 'X'; คืน (n); } int main () {คำทักทายถ่าน [5] = {'H', 'e', ​​'l', 'p', '\ 0'}; int len ​​= GetLength (คำทักทาย); ศาล << len << ":" << ทักทาย; // เอาท์พุท: 5: HXlp} ใน C # คุณจะต้องเขียน: int len ​​= GetLength (คำทักทายการอ้างอิง) ซึ่งจะส่งสัญญาณธงคำเตือนขนาดใหญ่ของ "เฮ้คำทักทายจะไม่เหมือนเดิมหลังจากที่คุณเรียกสิ่งนี้" และอย่างมาก ลดข้อบกพร่อง
Dustin_00

19

มีหลายวิธี; แต่ถ้าคุณไม่ต้องการสร้างวัตถุหรือโครงสร้างใหม่หรืออะไรทำนองนี้คุณสามารถทำเช่นนี้ได้หลังจาก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");

    }

13

ใน C # 7 มีTupleไวยากรณ์ใหม่:

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

คุณสามารถส่งคืนสิ่งนี้เป็นบันทึก:

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

คุณยังสามารถใช้ไวยากรณ์ deconstructor ใหม่:

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

ระมัดระวังกับอนุกรม แต่ทั้งหมดนี้เป็นน้ำตาลประโยค - ในรหัสเรียบเรียงจริงนี้จะเป็นTuple<string, int>(เป็นต่อคำตอบที่ได้รับการยอมรับ ) ด้วยItem1และItem2แทนและfoo barนั่นหมายความว่าการทำให้เป็นอนุกรม (หรือดีซีเรียลไลเซชั่น) จะใช้ชื่อคุณสมบัติเหล่านั้นแทน

ดังนั้นสำหรับการทำให้เป็นอนุกรมประกาศคลาสเรกคอร์ดและส่งคืนนั้นแทน

ใหม่ใน C # 7 เป็นไวยากรณ์ที่ปรับปรุงสำหรับoutพารามิเตอร์ ตอนนี้คุณสามารถประกาศoutอินไลน์ซึ่งเหมาะกว่าในบางบริบท:

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

อย่างไรก็ตามส่วนใหญ่คุณจะใช้สิ่งนี้ในห้องสมุดของ. NET แทนที่จะเป็นหน้าที่ของคุณเอง


โปรดทราบว่าคุณอาจต้องติดตั้งแพคเกจ Nuget System.ValueTuple ทั้งนี้ขึ้นอยู่กับรุ่น. Net ที่คุณกำหนดเป้าหมาย
Licht

ฉันกำลังจะตอบคำถามข้างต้น ;-)
Jeyara

12

บางคำตอบแนะนำให้ใช้พารามิเตอร์หมดแต่ฉันไม่แนะนำให้ใช้เนื่องจากไม่สามารถใช้กับวิธีการแบบอะซิงโครนัสได้ ดู สิ่งนี้สำหรับข้อมูลเพิ่มเติม

คำตอบอื่น ๆ ที่ระบุไว้โดยใช้ Tuple ซึ่งฉันอยากจะแนะนำเช่นกัน แต่การใช้คุณสมบัติใหม่ที่แนะนำใน 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}.");

ข้อมูลเพิ่มเติมสามารถพบได้ที่นี่


11

มีหลายวิธีในการทำเช่นนี้ คุณสามารถใช้refพารามิเตอร์:

int Foo(ref Bar bar) { }

สิ่งนี้ผ่านการอ้างอิงไปยังฟังก์ชันดังนั้นจึงอนุญาตให้ฟังก์ชันแก้ไขวัตถุในสแต็กของรหัสโทรศัพท์ ในขณะที่นี่ไม่ใช่ในทางเทคนิคค่า "คืน" มันเป็นวิธีที่จะมีฟังก์ชั่นทำสิ่งที่คล้ายกัน ในโค้ดข้างต้นฟังก์ชั่นจะกลับintและ (อาจ) barปรับเปลี่ยน

อีกวิธีที่คล้ายกันคือการใช้outพารามิเตอร์ outพารามิเตอร์เป็นเหมือนกันกับrefพารามิเตอร์ที่มีการเพิ่มเติมกฎบังคับใช้คอมไพเลอร์ กฎนี้คือถ้าคุณส่งoutพารามิเตอร์ไปยังฟังก์ชั่นฟังก์ชั่นนั้นจะต้องตั้งค่าของมันก่อนที่จะกลับมา นอกเหนือจากกฎนั้นoutพารามิเตอร์ทำงานเหมือนrefพารามิเตอร์

วิธีสุดท้าย (และดีที่สุดในกรณีส่วนใหญ่) คือการสร้างประเภทที่ห่อหุ้มค่าทั้งสองและอนุญาตให้ฟังก์ชั่นเพื่อกลับไปที่:

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

FooBar Foo(Bar bar) { }

วิธีการขั้นสุดท้ายนี้ง่ายขึ้นและง่ายต่อการอ่านและทำความเข้าใจ


11

ไม่คุณไม่สามารถส่งคืนค่าหลายค่าจากฟังก์ชั่นใน 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';
}

10

ใน C # 4 คุณจะสามารถใช้การสนับสนุนในตัวสำหรับสิ่งอันดับเพื่อจัดการสิ่งนี้ได้อย่างง่ายดาย

ในขณะเดียวกันมีสองตัวเลือก

ก่อนอื่นคุณสามารถใช้พารามิเตอร์ ref หรือ out เพื่อกำหนดค่าให้กับพารามิเตอร์ของคุณซึ่งจะถูกส่งกลับไปยังรูทีนการเรียก

ดูเหมือนว่า:

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

ประการที่สองคุณสามารถสรุปค่าที่ส่งคืนของคุณลงในโครงสร้างหรือคลาสแล้วส่งกลับเป็นสมาชิกของโครงสร้างนั้น KeyValuePair ทำงานได้ดีสำหรับ 2 - สำหรับมากกว่า 2 คุณจะต้องมีคลาสหรือโครงสร้างแบบกำหนดเอง


7

คุณสามารถลองใช้ "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


5

คลาสโครงสร้างคอลเลกชันและอาร์เรย์สามารถมีหลายค่า พารามิเตอร์เอาต์พุตและการอ้างอิงยังสามารถตั้งค่าในฟังก์ชั่น คืนค่าหลายค่าเป็นไปได้ในภาษาแบบไดนามิกและฟังก์ชั่นการทำงานโดยวิธีการ tuples แต่ไม่ได้อยู่ใน C #


4

ส่วนใหญ่มีสองวิธี 1. ใช้พารามิเตอร์ out / ref 2. ส่งคืนอาเรย์ของวัตถุ


นอกจากนี้ยังมีสิ่งอันดับและค่าผลตอบแทนหลายรายการเป็นน้ำตาลแบบน้ำตาลสำหรับสิ่งอันดับ
Aneves

4

นี่คือพื้นฐาน Twoวิธีการ :

1) การใช้ ' out' เป็นพารามิเตอร์ คุณสามารถใช้ 'ออก' สำหรับทั้งรุ่น 4.0 และรุ่นรองได้เช่นกัน

ตัวอย่างของ 'ออก':

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:

คืนค่า DataType หลายค่าโดยใช้ 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

หมายเหตุ: การ ใช้ Tuple นั้นถูกต้องจาก Framework 4.0 ขึ้นไป ประเภทเป็นTuple classมันจะถูกจัดสรรในตำแหน่งแยกต่างหากบนฮีปที่มีการจัดการในหน่วยความจำ เมื่อคุณสร้างคุณไม่สามารถเปลี่ยนค่าของมันTuple fieldsนี้จะทำให้มากขึ้นเช่นTuplestruct


4
<--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);

ฉันหวังว่ามันจะได้ผล


3

วิธีการผู้รับมอบสิทธิ์สามารถให้ค่าหลายค่าแก่ผู้โทร ขอยืมนี้จากคำตอบของฉันที่นี่และใช้นิด ๆ หน่อย ๆ จากคำตอบที่ได้รับการยอมรับของ Hadas

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

ผู้โทรจัดเตรียมแลมบ์ดา (หรือฟังก์ชั่นที่ตั้งชื่อไว้) และความช่วยเหลือในการจัดเก็บข้อมูลด้วยการคัดลอกชื่อตัวแปรจากผู้รับมอบสิทธิ์

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

2

เพียงใช้ในลักษณะ OOP คลาสเช่นนี้:

class div
{
    public int remainder;

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

ฟังก์ชั่นสมาชิกส่งกลับความฉลาดทางที่ผู้โทรส่วนใหญ่มีความสนใจเป็นหลักนอกจากนี้มันจะเก็บส่วนที่เหลือเป็นสมาชิกข้อมูลซึ่งผู้โทรสามารถเข้าถึงได้ง่ายในภายหลัง

วิธีนี้คุณสามารถมี "คืนค่า" เพิ่มเติมมีประโยชน์มากถ้าคุณใช้การเรียกฐานข้อมูลหรือเครือข่ายซึ่งอาจต้องใช้ข้อความแสดงข้อผิดพลาดจำนวนมาก แต่ในกรณีที่เกิดข้อผิดพลาดเท่านั้น

ฉันป้อนโซลูชันนี้ในคำถาม C ++ ที่ OP อ้างถึง


2

จากนี้บทความคุณสามารถใช้สามตัวเลือกเป็นโพสต์ที่กล่าวข้างต้น

KeyValuePairเป็นวิธีที่รวดเร็วที่สุด

ออกเป็นที่สอง

Tupleนั้นช้าที่สุด

อย่างไรก็ตามสิ่งนี้ขึ้นอยู่กับสิ่งที่ดีที่สุดสำหรับสถานการณ์ของคุณ


2

รุ่นในอนาคตของ C # จะรวมชื่อ tuples ดูที่เซสชั่น channel9 นี้สำหรับการสาธิต https://channel9.msdn.com/Events/Build/2016/B889

ข้ามไปที่ 13:00 สำหรับสิ่ง tuple สิ่งนี้จะอนุญาต:

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

int resultsum = Tally(numbers).sum

(ตัวอย่างที่ไม่สมบูรณ์จากวิดีโอ)


2

คุณสามารถใช้วัตถุแบบไดนามิก ฉันคิดว่ามันอ่านง่ายกว่า Tuple

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;
}

3
คุณสูญเสียการตรวจสอบประเภทเวลาคอมไพล์
Micha Wiedenmann

1

วิธีที่จะทำ:

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) Tuple - 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) สร้าง class / struct ของคุณเอง

ns -> nanoseconds

อ้างอิง: หลายผลตอบแทนค่า


0

คุณสามารถลองสิ่งนี้

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

1
สิ่งนี้ไม่ส่งคืนค่าหลายค่าจริงๆ ส่งคืนค่าการรวบรวมเดียว
Matthew Haugen

นอกจากนี้ทำไมไม่ใช้yield return "value1"; yield return "value2";เพื่อไม่ต้องสร้างใหม่อย่างชัดเจนstring[]?
โทมัส Flinkow

0

คุณยังสามารถใช้ 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;
}

-7

คำตอบอย่างรวดเร็วเป็นพิเศษสำหรับประเภทอาร์เรย์คืน:

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[1];

3
"โปรแกรมเมอร์ต้องการเวลาและวิธีการที่ไม่สามารถให้อภัยได้" หมายความว่าอย่างไร?
โทมัส Flinkow

2
คุณใช้ผลลัพธ์ [0] สองครั้ง มันเป็นความผิดปกติของสิ่งนี้ด้วย
symbiont

1
ไม่ต้องสงสัยเลยว่านี่เป็นคำตอบที่ไม่อาจลืมได้
Luis Teijon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.