C # Kodumda .NET 4.0 Tuples Kullanımı Kötü Tasarım Kararı mı?


166

Tuple sınıfının .net 4'e eklenmesi ile bunları tasarımımda kullanmanın kötü bir seçim olup olmadığına karar vermeye çalışıyorum. Gördüğüm gibi, bir Tuple bir sonuç sınıfı yazmak için bir kısayol olabilir (eminim başka kullanımları da vardır).

Yani bu:

public class ResultType
{
    public string StringValue { get; set; }
    public int IntValue { get; set; }
}

public ResultType GetAClassedValue()
{
    //..Do Some Stuff
    ResultType result = new ResultType { StringValue = "A String", IntValue = 2 };
    return result;
}

Buna eşdeğerdir:

public Tuple<string, int> GetATupledValue()
{
    //...Do Some stuff
    Tuple<string, int> result = new Tuple<string, int>("A String", 2);
    return result;
}

Tuples'ın noktasını kaçırmam olasılığını bir kenara bırakmak, Tuple ile örnek kötü bir tasarım seçimi mi? Bana göre daha az dağınık gibi görünüyor, ancak kendini belgeleyen ve temiz değil. Yani, tür ile ResultType, daha sonra sınıfın her bölümünün ne anlama geldiği çok açıktır, ancak korumak için ekstra kodunuz vardır. İle Tuple<string, int>her birinin neyi Itemtemsil ettiğini bulup bulmanız gerekecek , ancak daha az kod yazıp koruyacaksınız.

Bu seçim ile yaşadığınız herhangi bir deneyim büyük mutluluk duyacağız.


16
@Boltbait: tuple set teorisinden olduğu için en.wikipedia.org/wiki/Tuple
Matthew Whited

16
@BoltBait: "Tuple", sıralı bir değerler kümesidir ve illa ki bir veritabanındaki satırlarla ilgisi yoktur.
Hayal kırıklığına

19
Bazı iyi tuple açma eylemi olsaydı c # Tuples daha güzel olurdu :)
Justin

4
@ John Saunders Sorum özellikle c # tasarım kararları hakkında. Başka hiçbir .net dili kullanmıyorum, bu yüzden tupl'lerin onları nasıl etkilediğinden emin değilim. Bu yüzden c # olarak işaretledim. Benim için makul görünüyordu ama sanırım .net değişikliği gayet iyi.
Jason Webb

13
@John Saunders: Tamamen C # ile yazılmış bir uygulamada Tuples'ı kullanmama veya kullanmama ile ilgili tasarım kararları hakkında sorular sorduğundan eminim. C # dilini kullanmaya başlayan tasarım kararlarını sorduğuna inanmıyorum.
Brett Widmeier

Yanıtlar:


163

Tuples, hem oluşturmayı hem de kullanmayı kontrol ederseniz harikadır - onları anlamak için gerekli olan bağlamı koruyabilirsiniz.

Ancak herkese açık bir API'da daha az etkilidirler. Tüketici (siz değil), özellikle benzeri şeyler için belgeleri tahmin etmek veya aramak zorundadır Tuple<int, int>.

Onları özel / dahili üyeler için, ancak kamu / korunan üyeler için sonuç sınıfları kullanırdım.

Bu cevapta bazı bilgiler de var.


19
Kamu / özel sektör arasındaki fark gerçekten önemlidir, getirdiğiniz için teşekkürler. Herkese açık API'nızda tuples döndürmek gerçekten kötü bir fikir, ancak dahili olarak işlerin sıkıca birleştirilebileceği (ancak sorun değil ).
Clinton Pierce

36
Sıkıca bağlı mı yoksa sıkıca bağlı mı? ;)
contactmatt

Burada uygun belgeler işe yarayabilir mi? Örneğin, Scala'nın StringOps(temelde Java için bir "genişletme yöntemleri" sınıfı String) bir yöntemi vardır parition(Char => Boolean): (String, String)(yüklemi alır, 2 dizgiden oluşan bir demet döndürür). Çıktının ne olduğu açıktır (açıkçası biri yüklemin doğru olduğu ve diğerinin yanlış olduğu karakterler olacaktır, ancak hangisinin hangisi olduğu açık değildir). Bunu temizleyen belgelerdir (ve hangisi kullanımda bunu netleştirmek için desen eşleştirme kullanılabilir).
Kat

@Mike: Bu doğru ve kolay yanlış yapmak, bir yerde birisi için acıya neden olacak bir API damgasını zorlaştırır :-)
Bryan Watts

79

Gördüğüm gibi, bir Tuple bir sonuç sınıfı yazmak için bir kısayoldur (başka kullanımlar da olduğundan eminim).

Gerçekten de başka değerli kullanımlar da vardırTuple<> - bunların çoğu, benzer bir yapıyı paylaşan belirli bir grup grubun semantiğinin soyutlanmasını ve basitçe sıralı değerler kümesi olarak ele alınmasını içerir. Her durumda, tuples'ın bir avantajı, ad alanınızı, özellikleri göstermeyen ancak yöntemleri değil yalnızca veri sınıflarıyla karıştırmaktan kaçınmalarıdır.

Aşağıda makul bir kullanım örneği verilmiştir Tuple<>:

var opponents = new Tuple<Player,Player>( playerBob, playerSam );

Yukarıdaki örnekte bir çift rakibi temsil etmek istiyoruz, bir grup yeni bir sınıf yaratmak zorunda kalmadan bu örnekleri eşleştirmenin uygun bir yoludur. İşte başka bir örnek:

var pokerHand = Tuple.Create( card1, card2, card3, card4, card5 );

Bir poker eli sadece bir kart seti olarak düşünülebilir ve bu kavramı ifade etmenin makul bir yolu olabilir.

Tuples'ın noktasını kaçırmama ihtimalini bir kenara bırakırsak, Tuple ile örnek kötü bir tasarım seçimi midir?

Tuple<>Genel tür için genel bir API'nın parçası olarak güçlü yazılan örnekleri döndürmek nadiren iyi bir fikirdir. Kendinizi tanıdığınız gibi, tuples ilgili tarafların (kütüphane yazarı, kütüphane kullanıcısı) kullanılan tuple tiplerinin amacı ve yorumu konusunda önceden anlaşmasını gerektirir. Sezgisel ve açık API'lar oluşturmak için yeterince zorlayıcıdır, Tuple<>yalnızca herkese açık olarak API'nın amacını ve davranışını gizler.

Anonim türler de bir tür gruptur - ancak, güçlü bir şekilde yazılırlar ve türe ait özellikler için açık, bilgilendirici adlar belirtmenize izin verir. Ancak anonim türlerin farklı yöntemlerde kullanılması zordur - öncelikle projeksiyonların normalde ad atamak istemeyeceğimiz türler üreteceği LINQ gibi teknolojileri desteklemek için eklenmiştir. (Evet, aynı tür ve adlandırılmış özelliklere sahip anonim türlerin derleyici tarafından birleştirildiğini biliyorum).

Temel kuralım: Genel arayüzünüzden döndürürseniz - adlandırılmış bir tür yapın .

Tuples'ı kullanmanın diğer temel kuralı şudur: name yöntemi argümanları ve türün localc değişkenleri Tuple<>olabildiğince açık bir şekilde - adı, grubun öğeleri arasındaki ilişkilerin anlamını temsil ettirin . var opponents = ...Örneğimi düşün .

Aşağıda, yalnızca kendi derlememde kullanmak üzere yalnızcaTuple<> veri türü bildirmekten kaçındığım gerçek dünya örneği örneği . Durum, anonim türler içeren genel sözlükler kullanırken, yöntem adında bulunamayan bir parametre gerektirdiğinden, sözlükteki öğeleri bulmak için yöntemi kullanmak zorlaşır :TryGetValue()out

public static class DictionaryExt 
{
    // helper method that allows compiler to provide type inference
    // when attempting to locate optionally existent items in a dictionary
    public static Tuple<TValue,bool> Find<TKey,TValue>( 
        this IDictionary<TKey,TValue> dict, TKey keyToFind ) 
    {
        TValue foundValue = default(TValue);
        bool wasFound = dict.TryGetValue( keyToFind, out foundValue );
        return Tuple.Create( foundValue, wasFound );
    }
}

public class Program
{
    public static void Main()
    {
        var people = new[] { new { LastName = "Smith", FirstName = "Joe" },
                             new { LastName = "Sanders", FirstName = "Bob" } };

        var peopleDict = people.ToDictionary( d => d.LastName );

        // ??? foundItem <= what type would you put here?
        // peopleDict.TryGetValue( "Smith", out ??? );

        // so instead, we use our Find() extension:
        var result = peopleDict.Find( "Smith" );
        if( result.First )
        {
            Console.WriteLine( result.Second );
        }
    }
}

PS Sözlüklerde anonim türlerden kaynaklanan sorunların üstesinden gelmenin başka bir (daha basit) yolu var ve bu, varderleyicinin sizin için türü 'çıkarmasına' izin vermek için anahtar kelimeyi kullanmaktır . İşte bu sürüm:

var foundItem = peopleDict.FirstOrDefault().Value;
if( peopleDict.TryGetValue( "Smith", out foundItem ) )
{
   // use foundItem...
}

5
@stakx: Evet, katılıyorum. Ancak unutmayın - örnek, büyük ölçüde, a'nın kullanımının mantıklı Tuple<> olabileceği durumları göstermeyi amaçlamaktadır . Her zaman alternatifler vardır ...
LBushkin

1
TryGetValue veya TryParse gibi parametreleri bir Tuple ile değiştirmenin, genel API'nin bir Tuple döndürmesi mantıklı olabilecek birkaç durumdan biri olduğunu düşünüyorum. Aslında, en az bir .NET dili bu API'yi sizin için otomatik olarak değiştirir.
Joel Mueller

1
@stakx: Tüller de değişmezken diziler değişmiyor.
Robert Paulson

2
Tuples'ın sadece değişmez poker oyuncusu nesneleri olarak yararlı olduğunu anladım.
Gennady Vanin Геннадий Ванин

2
+1 Harika cevap - Aslında fikrimi biraz değiştiren iki ilk örneğinizi seviyorum. Bir grubun en azından özel bir yapı veya tip kadar uygun olduğu yerlerde daha önce hiç örnek görmedim. Ancak, bana son "gerçek yaşam örneğiniz" artık fazla değer katmıyor gibi görünüyor. İlk iki örnek mükemmel ve basittir. Sonuncusu anlamak biraz zor ve "PS" türünüz onu işe yaramaz hale getiriyor, çünkü alternatif yaklaşımınız çok daha basit ve tuples gerektirmiyor.
chiccodoro

18

Tuples yararlı olabilir ... ama daha sonra bir ağrı da olabilir. Geri dönen bir yönteminiz varsa, Tuple<int,string,string,int>bu değerlerin ne olduğunu daha sonra nasıl bilirsiniz. Öyle ID, FirstName, LastName, Ageya da öyleydiler UnitNumber, Street, City, ZipCode.


9

Tuples bir C # programcı bakış açısından CLR için oldukça underwhelming ek vardır. Uzunluğu değişen bir öğe koleksiyonunuz varsa, derleme sırasında benzersiz statik adlara sahip olmalarına gerek yoktur.

Ancak sabit uzunluktaki bir koleksiyonunuz varsa, bu koleksiyondaki sabit konumların her birinin belirli bir önceden tanımlanmış anlamı olduğu anlamına gelir. Ve öyle hep ziyade önemini hatırlamak zorunda kalmak yerine, bu durumda onlara uygun statik isim vermek daha iyi Item1, Item2vb

C # 'daki anonim sınıflar, tuplelerin en yaygın özel kullanımına mükemmel bir çözüm sağlar ve öğelere anlamlı isimler verir, bu yüzden aslında bu anlamda üstündürler. Tek sorun, adlandırılmış yöntemlerden sızamayacaklarıdır. Ben C # tuples için belirli bir destek daha kısıtlama (belki de sadece özel yöntemler için) kaldırdı görmek tercih ederim:

private var GetDesserts()
{
    return _icecreams.Select(
        i => new { icecream = i, topping = new Topping(i) }
    );
}

public void Eat()
{
    foreach (var dessert in GetDesserts())
    {
        dessert.icecream.AddTopping(dessert.topping);
        dessert.Eat();
    }
}

Genel bir özellik olarak, .net için birkaç özel anonim tür için bir standart tanımlamak için, örneğin struct var SimpleStruct {int x, int y;}basit yapılar ile ilişkili bir kılavuzla başlayan bir isme sahip bir yapı tanımlayacaktı. {System.Int16 x}{System.Int16 y}ekli gibi bir şey var ; bu GUID ile başlayan herhangi bir adın yalnızca bu öğeleri ve belirli belirtilen içerikleri içeren bir yapıyı temsil etmesi gerekir; aynı isim için birden fazla tanım kapsamındaysa ve eşleşiyorsa, hepsi aynı tür olarak kabul edilir.
supercat

Böyle bir şey, değişebilen yapının ve değişmez sınıf ve yapıların yanı sıra eşleşen yapının eşleşen anlambilim anlamına geldiği durumlarda kullanılması gereken arayüzler ve delegeler de dahil olmak üzere birkaç tür türü için yararlı olacaktır. Aynı parametrelerin değiştirilebilir olarak kabul edilmeyen iki delege türüne sahip olmanın yararlı olmasının nedenleri kesinlikle olsa da, bir yöntemin bazı parametreler kombinasyonunu alan ancak bunun ötesinde bir delege istediği belirtilebilirse de yararlı olacaktır. ne tür bir delege olduğunu umursamıyorum.
supercat

İki farklı kişi ref, tek bir parametreye ihtiyaç duyan giriş delegeleri olarak işlevler yazmak istiyorsa , her iki işleve geçirilebilen bir delegeye sahip olmanın tek yolunun, bir kişinin üretip derlemesi delege yazın ve karşı inşa etmek için diğerine verir. Her iki insanın da iki türün eşanlamlı olarak kabul edilmesi gerektiğini göstermesinin bir yolu yoktur.
supercat

İsimsiz sınıfları nerede kullanmak yerine daha somut örnekleriniz var Tuplemı? Ben sadece tuples kullandığım benim kod temeli 50 yerlerden sıyrılmış ve tüm dönüş değerleri (genellikle yield return) ya da başka bir yerde kullanılan koleksiyon öğeleri, bu yüzden anonim sınıflar için gitmek.

2
@JonofAllTrades - görüşler muhtemelen buna göre değişir, ancak herkese açık yöntemleri başka biri tarafından kullanılacakmış gibi tasarlamaya çalışırım , birisi ben olsa bile, kendime iyi müşteri hizmeti veriyorum! Bir işlevi yazdığınızdan daha fazla çağırırsınız. :)
Daniel Earwicker

8

Anahtar kelimeye benzer şekilde var, kolaylık sağlamak için tasarlanmıştır - ancak kolayca kötüye kullanılabilir.

En alçakgönüllü görüşüme göre, Tuplebir dönüş sınıfı olarak göstermeyin . Bir hizmetin veya bileşenin veri yapısı gerektiriyorsa özel olarak kullanın, ancak iyi bilinen iyi bilinen sınıfları genel yöntemlerden döndürün.

// one possible use of tuple within a private context. would never
// return an opaque non-descript instance as a result, but useful
// when scope is known [ie private] and implementation intimacy is
// expected
public class WorkflowHost
{
    // a map of uri's to a workflow service definition 
    // and workflow service instance. By convention, first
    // element of tuple is definition, second element is
    // instance
    private Dictionary<Uri, Tuple<WorkflowService, WorkflowServiceHost>> _map = 
        new Dictionary<Uri, Tuple<WorkflowService, WorkflowServiceHost>> ();
}

2
Genel "RAD" dilleri (Java en iyi örnektir) her zaman güvenliği seçmiş ve ayak tipi senaryolarında kendinizi çekmekten kaçınmıştır. Microsoft'un C # ile bazı şanslar almasına ve dile kötüye kullanılsa bile güzel bir güç vermesine sevindim.
Matt Greer

4
Var anahtar sözcüğünü kötüye kullanmak mümkün değildir. Belki dinamik demek istedin?
Chris Marisic

@Crisris Marisic, sadece aynı senaryoda demek istemediğimi açıklığa kavuşturmak için - kesinlikle haklısınız, vargeri alınamaz veya beyan edilen kapsamı dışında var olamaz. Bununla birlikte, içinde kullanmak mümkün olduğunu fazla amacına uygun olarak ve "kötüye" olarak
Johnny g

5
Ben hala bu var istismar dönem olamaz duruyorum. Daha kısa bir değişken tanımı yapmak sadece bir anahtar kelimedir. Tartışmanız belki de anonim türlerle ilgilidir, ancak bunlar gerçekten istismar edilemez, çünkü hala normal olarak statik olarak bağlantılı türler şimdi dinamik oldukça farklı bir hikaye.
Chris Marisic

4
var, aşırı kullanılırsa bazen kodu okuyan kişi için sorunlara neden olabileceği anlamında kötüye kullanılabilir. Özellikle Visual Studio'da değilseniz ve akıllılığınız yoksa.
Matt Greer

5

Gibi bir sınıf kullanmak ResultTypedaha açıktır. (Tuple ile onlar aranmak oysa sınıfta alanlara anlamlı adlar verebilir Item1ve Item2). İki alanın türleri aynı ise, bu daha da önemlidir: ad, aralarında açıkça ayrım yapar.


Küçük bir ek avantaj: bir sınıfın parametrelerini güvenle yeniden sıralayabilirsiniz. Bunu yapmak bir tuple için kodu kırar ve alanlar benzer tiplere sahipse, bu derleme zamanında algılanamayabilir.

Katılıyorum, Tuples, bir geliştirici anlamlı mülk adlarını gruplandırmak için anlamlı bir sınıf adı düşünmek için enerjiden yoksun olduğunda kullanılır. Programlama iletişim ile ilgilidir. Tuples iletişim için bir antipatterntir. Microsoft'u geliştiricileri iyi tasarım kararları almaya zorlamak için dilden çıkarmayı tercih ederdim.
mike gold

5

Tuples'ı bir decorate-sort-underate deseninde kullanmaya ne dersiniz? (Perl halkı için Schwartz Dönüşüm). İşte emin olmak için tartışmalı bir örnek, ancak Tuples bu tür şeyleri ele almanın iyi bir yolu gibi görünüyor:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] files = Directory.GetFiles("C:\\Windows")
                    .Select(x => new Tuple<string, string>(x, FirstLine(x)))
                    .OrderBy(x => x.Item2)
                    .Select(x => x.Item1).ToArray();
        }
        static string FirstLine(string path)
        {
            using (TextReader tr = new StreamReader(
                        File.Open(path, FileMode.Open)))
            {
                return tr.ReadLine();
            }
        }
    }
}

Şimdi, iki öğeden oluşan bir Object [] veya bu özel örnekte iki öğeden oluşan bir dize [] kullanabilirdim. Mesele şu ki, dahili olarak kullanılan ve okunması oldukça kolay olan bir Tuple'daki ikinci element olarak herhangi bir şey kullanabilirdim.


3
Yapıcı yerine Tuple.Create kullanabilirsiniz. Daha kısa.
Kugel

anonim tip çok daha okunaklı olacaktır; x yerine gerçek değişken adları kullanır gibi
Dave Cousineau

O olur şimdi . Bu bir SO problemidir, yıllar ve yıllar önce gönderilen cevaplar asla yeni teknoloji için temizlenmez veya güncellenmez.
Clinton Pierce

4

IMO bu "tuples" temelde isimsiz üyeleri ile tüm kamu erişim anonim structtürleri .

Sadece sen çok sınırlı kapsamda, hızlı bir şekilde birlikte bazı verileri blob gerektiğinde ben başlık olur kullanırsınız yerleştirin. Verilerin anlambilimi açık olmalıdır , bu nedenle kodun okunması zor değildir. Yani (row, col) için bir tuple ( int, int) kullanmak mantıklı görünüyor. Ancak struct, adlandırılmış üyelerle bir avantaj bulmak için zorlandım (bu yüzden hata yapılmaz ve satır / sütun yanlışlıkla değiştirilmez)

Arayan kişiye veri gönderiyorsanız veya bir arayandan veri kabul ediyorsanız, gerçekten structadlandırılmış üyelere sahip bir.

Basit bir örnek verelim:

struct Color{ float r,g,b,a ; }
public void setColor( Color color )
{
}

Tuple versiyonu

public void setColor( Tuple<float,float,float,float> color )
{
  // why?
}

Adlandırılmış üyelere sahip bir yapı yerine tuple kullanmanın herhangi bir avantajını görmüyorum. Adsız üyelerin kullanılması, kodunuzun okunabilirliği ve anlaşılabilirliği için bir adım geri atılır.

Tuple struct, gerçek adlandırılmış üyelerle bir oluşturmaktan kaçınmam için bana tembel bir yol olarak bakıyor . Sizi / veya kodunuzla karşılaşan birisinin adlandırılmış üyelere ihtiyaç duyacağını gerçekten hissettiğiniz tuplein aşırı kullanımı, eğer bir tane görürsem A Bad Thing ™ 'dir.


3

Beni yargılama, ben bir uzman değilim, ama şimdi C # 7.x yeni Tuples ile, gibi bir şey dönebilir:

return (string Name1, int Name2)

En azından şimdi adlandırabilirsiniz ve geliştiriciler bazı bilgiler görebilir.


2

Elbette bağlıdır! Söylediğiniz gibi, bir grup yerel tüketim için bazı öğeleri birlikte gruplamak istediğinizde kod ve zamandan tasarruf edebilir. Bunları ayrıca, somut bir sınıf geçirirseniz yapabileceğinizden daha genel işlem algoritmaları oluşturmak için de kullanabilirsiniz. Kaç kez hızlı bir şekilde bir yöntemden diğerine geçmek için KeyValuePair veya DataRow ötesinde bir şey olmasını dilediğimi hatırlayamıyorum.

Öte yandan, aşırıya kaçmak ve sadece içerdiklerini tahmin edebileceğiniz tuples etrafında geçmek oldukça mümkündür. Sınıflar arasında bir demet kullanacaksanız, belki bir somut sınıf oluşturmak daha iyi olacaktır.

Elbette ölçülü olarak kullanıldığında, tuples daha özlü ve okunabilir koda yol açabilir. Tuples'ın diğer dillerde nasıl kullanıldığına dair örnekler için C ++, STL ve Boost'a bakabilirsiniz, ancak sonunda hepimiz .NET ortamına en uygun olanları bulmak için deney yapmalıyız.


1

Tuples .NET 4'te işe yaramaz bir çerçeve özelliği. C # 4.0 ile büyük bir fırsat kaçırıldı düşünüyorum. Ben adlandırılmış üyeleri ile tuples sahip olmak isterdim, böylece Value1 , Value2 , vb yerine adıyla bir tuple çeşitli alanlarına erişebilir ...

Bir dil (sözdizimi) değişikliği gerektirecekti, ama çok yararlı olurdu.


Tuples nasıl bir "dil özelliği"? Tüm .net dillerinde kullanılabilir bir sınıf değil mi?
Jason Webb

11
Belki de C # için nispeten işe yaramaz. Ancak System.Tuple, C # nedeniyle çerçeveye eklenmedi. F # ve diğer diller arasında birlikte çalışabilirliği kolaylaştırmak için eklendi.
Joel Mueller

@Jason: Bunun bir dil özelliği olduğunu söylemedim (yanlış yazdım, ama siz bu yorumu yapmadan önce düzelttim).
Philippe Leybaert

2
@Jason - tuples için doğrudan desteği olan diller, tuples'i bileşen değerlerine ayırmak için örtük desteğe sahiptir. Bu dillerde yazılmış kod, hiçbir zaman, hiçbir zaman, Item1, Item2 özelliklerine erişmez. let success, value = MethodThatReturnsATuple()
Joel Mueller

@Joel: Bu soru C # olarak etiketlendi, bu yüzden bir şekilde C # hakkında. Hala dilde birinci sınıf bir özelliğe dönüştürebileceklerini düşünüyorum.
Philippe Leybaert

1

Şahsen bir Tuple'i bir dönüş türü olarak kullanmazdım çünkü değerlerin neyi temsil ettiğine dair bir gösterge yoktur. Tuple'lerin bazı değerli kullanımları vardır, çünkü nesnelerin aksine değer tipleridir ve bu nedenle eşitliği anlarlar. Bu nedenle, çok parçalı bir anahtara ihtiyacım olursa bunları sözlük anahtarları olarak veya birden çok değişkene göre gruplandırmak ve iç içe gruplamalar istemiyorsanız (İç içe gruplamaları kim ister?). Aşırı ayrıntılarla ilgili sorunun üstesinden gelmek için bunları bir yardımcı yöntemle oluşturabilirsiniz. Üyelere (Öğe1, Öğe2 vb. Aracılığıyla) sık sık erişiyorsanız, muhtemelen bir yapı veya anonim sınıf gibi farklı bir yapı kullanmanız gerektiğini unutmayın.


0

Her ikisi de, dizilerini kullandım Tupleve yeni ValueTuplefarklı senaryolar bir dizi ve şu sonuca vardı: kullanmayın .

Her seferinde aşağıdaki sorunlarla karşılaştım:

  • güçlü adlandırma eksikliği nedeniyle kod okunamaz hale geldi;
  • temel sınıf DTO ve alt sınıf DTO'lar gibi sınıf hiyerarşi özelliklerini kullanamaz;
  • birden fazla yerde kullanılıyorlarsa, temiz bir sınıf adı yerine bu çirkin tanımları kopyalayıp yapıştırırsınız.

Bence tuples C # bir özellik değil, bir zarar vardır.

Biraz benzerim, ama çok daha az sert, eleştirim var Func<>ve Action<>. Bunlar birçok durumda yararlıdır, özellikle basit Actionve Func<type>değişkenler, ancak bunun ötesinde bir şey, bir delege türü oluşturmanın daha zarif, okunabilir, bakımı yapılabilir ve ref/ outparametreler gibi daha fazla özellik verdiğini buldum .


Ben adlandırılmış tuples bahsetti - ValueTuple- ve ben de onları sevmiyorum. Birincisi, adlandırma güçlü değil, daha çok bir öneri, karışıklık yapmak çok kolay çünkü örtülü olarak Tupleveya ValueTupleaynı sayı ve öğe türlerine atanabilir . İkincisi, kalıtım eksikliği ve tüm tanımı bir yerden bir yere yapıştırmak zorunda kalma ihtiyacı hala zararlıdır.
Sayın TA

Bu noktalara katılıyorum. Tuples'ı sadece üreticiyi ve tüketiciyi kontrol ettiğimde ve çok "uzakta" değilse kullanmaya çalışıyorum. Anlam, üretici ve tüketici aynı yöntemle = 'yakın', oysa üretici ve tüketici farklı meclislerde = 'ışık yılı uzakta'. Bir yöntemin başında tuples oluşturup sonunda kullanırsam? Tabii, bununla iyiyim. Ayrıca şartları ve benzerlerini de belgeliyorum. Ama evet, genel olarak doğru seçim olmadıklarına katılıyorum.
Mike Christiansen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.