2010-05-05 19 views
10

'un iki değerini döndürdüğü yöntemleri yazmam gerektiğinde, genellikle List<string> değerini döndüren şu koddaki gibi giderim. Ya da, örneğin kimlik ve dizgisi, daha sonra List<object> döndürüp, dizin dizin numarası ve yeniden yeniden değerleriyle seçin.İki değeri bir yöntemden döndürmenin en iyi yolu nedir?

Bu yeniden sıralama ve dizine göre başvuru dizini yetersiz görünüyor, dolayısıyla iki değer döndüren yöntemler için yeni bir alışkanlık geliştirmek istiyorum. Bunun için en iyi desen nedir?

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace MultipleReturns 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string extension = "txt"; 

      { 
       List<string> entries = GetIdCodeAndFileName("first.txt", extension); 
       Console.WriteLine("{0}, {1}", entries[0], entries[1]); 
      } 

      { 
       List<string> entries = GetIdCodeAndFileName("first", extension); 
       Console.WriteLine("{0}, {1}", entries[0], entries[1]); 
      } 

      Console.ReadLine(); 
     } 

     /// <summary> 
     /// gets "first.txt", "txt" and returns "first", "first.txt" 
     /// gets "first", "txt" and returns "first", "first.txt" 
     /// it is assumed that extensions will always match 
     /// </summary> 
     /// <param name="line"></param> 
     public static List<string> GetIdCodeAndFileName(string line, string extension) 
     { 
      if (line.Contains(".")) 
      { 
       List<string> parts = line.BreakIntoParts("."); 
       List<string> returnItems = new List<string>(); 
       returnItems.Add(parts[0]); 
       returnItems.Add(line); 
       return returnItems; 
      } 
      else 
      { 
       List<string> returnItems = new List<string>(); 
       returnItems.Add(line); 
       returnItems.Add(line + "." + extension); 
       return returnItems; 
      } 
     } 

    } 

    public static class StringHelpers 
    { 
     public static List<string> BreakIntoParts(this string line, string separator) 
     { 
      if (String.IsNullOrEmpty(line)) 
       return null; 
      else 
      { 
       return line.Split(new string[] { separator }, StringSplitOptions.None).Select(p => p.Trim()).ToList(); 
      } 
     } 
    } 
} 

Eklendi:

Ok, sayesinde herkes, ben, iyi, gerçekten out kolay okunması olmasıydı hiç düşünmemiştim "özel bir sınıf dönmek " cevaplar like kesmek gibi görünüyor beni ilk değişken bir şekilde dönen ve başka ikinci, burada özel bir sınıf dönen benim üstlenmeden geçerli:

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace MultipleReturns 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string extension = "txt"; 

      { 
       IdCodeFileNamePair pair = GetIdCodeAndFileName("first.txt", extension); 
       Console.WriteLine("{0}, {1}", pair.IdCode, pair.FileName); 
      } 

      { 
       IdCodeFileNamePair pair = GetIdCodeAndFileName("first", extension); 
       Console.WriteLine("{0}, {1}", pair.IdCode, pair.FileName); 
      } 

      Console.ReadLine(); 
     } 

     /// <summary> 
     /// gets "first.txt", "txt" and returns "first", "first.txt" 
     /// gets "first", "txt" and returns "first", "first.txt" 
     /// it is assumed that extensions will always match 
     /// </summary> 
     /// <param name="line"></param> 
     public static IdCodeFileNamePair GetIdCodeAndFileName(string line, string extension) 
     { 
      if (line.Contains(".")) 
      { 
       List<string> parts = line.BreakIntoParts("."); 
       List<string> returnItems = new List<string>(); 
       return new IdCodeFileNamePair { IdCode = parts[0], FileName = line }; 
      } 
      else 
      { 
       List<string> returnItems = new List<string>(); 
       return new IdCodeFileNamePair { IdCode = line, FileName = line + "." + extension }; 
      } 
     } 

    } 

    public static class StringHelpers 
    { 
     public static List<string> BreakIntoParts(this string line, string separator) 
     { 
      if (String.IsNullOrEmpty(line)) 
       return null; 
      else 
      { 
       return line.Split(new string[] { separator }, StringSplitOptions.None).Select(p => p.Trim()).ToList(); 
      } 
     } 
    } 

    public class IdCodeFileNamePair 
    { 
     public string IdCode { get; set; } 
     public string FileName { get; set; } 
    } 
} 
+0

@tehMick Bu etiketleri kaldırmak için neden kendinizin üstlendiğinizden emin değil misiniz? Benim için alakalı görünüyorlar. –

+8

En iyi çözümü unutma: Her yöntemin mantıklı bir şekilde bir şeyi döndürmesi için kodu yeniden düzenleyin. İki sonuç döndüren bir yönteme sahip olmanız, yöntemin yeniden düzenleme işleminden yararlanabileceğini gösteren kırmızı bir bayraktır. –

cevap

12

ben iki özellik (aşağıya bakın) veya (kendi yazmak zor şimdi .NET 4'te çerçeve içine pişmiş mevcut değil) bir demet kullanmak

class MyReturnValue 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
} 
2

için anahtar kelime out

http://msdn.microsoft.com/en-us/library/ee332485.aspx

Bu nesneler listesi belirli öğelerini döküm daha yolu iyidir.

+0

Sonuç nasıl düzgün bir şekilde başka bir yöntem çağrısı geçiriyorsunuz? –

+0

'int a; Foo (dışarı a); Bar (a); Kısacası, yapmazsınız. 'dışarıda' zarif değil, bazen gerekli. –

+0

@John: Dosya adı, herhangi bir sonraki yöntem çağrılarında ayrı bir parametre olmalıdır. Bu, her şey kadar temiz. –

0

Şablon hakkında Pair<T,V>? Tabii ki, aynı olanlar etrafından geçilecekse, bunun için özel veri türleri oluşturabilirsin, ama bu jenerik değil.

(belki Veya C#-fly on-sen sınıfları oluşturmak izin vermez güncelleme:? Ok bu biraz görmezden) Sen 4.0 ile başlayarak, bir tuple geri dönebilirler

+0

Evet, bir sinemayı anında oluşturabilirsin, ancak yerel kapsamda kalmalı, bu yüzden geri dönüş olamaz bir yöntemin değeri. –

8

.

+1

Bu topluluk wiki'yi kazayla mı yapıyordu? CW gönderileriniz için reeskont almazsınız! –

1

Neden public static void GetIdCodeAndFileName(string line, string extension, out string id, out string fileName)?

+0

Sonucu başka bir yöntem çağrısına nasıl düzgün bir şekilde iletirsiniz? –

+0

@John: Dosya adı her hangi bir sonraki yöntem çağrısında ayrı bir parametre olmalıdır. Bu, her şey kadar temiz. –

+0

Bu örnekte belki, soru daha genel değil miydi? –

0
ile hafif sınıf oluşturmak için ya tercih

Sadece düz C# 'de iki değer döndürmenin zarif bir yolu yoktur. out parametrelerini kullanmayı düşünmeme rağmen, List'u iade etmekten daha iyidir, bu çok bakımsız veya okunabilir değildir. C# geliştiricileri out bekler, doğrudan dil tarafından desteklenir ve ne yaptığı iyi anlaşılır.

4.0'dan başlayarak, bunun yerine Tuple'u kullanabilirsiniz.

1

Ya parazitleri kullanın ya da özelliklere sahip bir yapı oluşturun (özellik başlatıcı sözdizimi için) ve döndürün. Özel bir yapı/sınıf oluşturmak, geçirilmekte olan verilerle eşleşen değişken adlandırma avantajına sahiptir. Bu, kodu daha okunabilir hale getirir.

IdAndString GetIDAndString() 
{ 
    return new IdAndString() 
    { 
     ID = 1, 
     Str = "123" 
    }; 
} 

struct IdAndString 
{ 
    public int ID { get; set; } 
    public string Str { get; set; } 
} 
2

Başka bir seçenek KeyValuePair<int, string> döndürmektir.

1

Mark'ın önerdiği gibi bir Hafif nesnenin kullanılmasını öneririm. Ama başka modeller de var.

Başka bir basit yaklaşım ise, referans özelliğini kullanarak aramayı kullanın. Gibi arayan arayan tarafından doldurulan bir parametre olarak boş bir dizi gönderir.

İlgili konular