C # 코드에서 .NET 4.0 튜플을 사용하는 것이 좋지 않은 디자인 결정입니까?


166

튜플을 추가하면.net 4에 클래스 디자인에 사용하는 것이 나쁜 선택인지 여부를 결정하려고했습니다. 내가 보는 방식으로 Tuple 은 결과 클래스를 작성하는 지름길이 될 수 있습니다 (다른 용도도 있음).

그래서 이거:

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

이것과 동일합니다 :

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

옆으로 난 튜플의 지점을 잃었 가능성을 설정하며,이와 예입니다 튜플은 나쁜 디자인 선택? 나에게 그것은 덜 어수선 해 보이지만 자기 문서화와 깨끗함은 아닙니다. 유형과 함께 의미ResultType 을 사용하면 클래스의 각 부분이 무엇을 의미하는지 명확하게 알 수 있지만 유지 관리해야 할 추가 코드가 있습니다. 를 사용하면 Tuple<string, int>각각이 Item나타내는 내용을 찾아서 파악해야 하지만 코드를 적게 작성하고 유지 관리해야합니다.

이 선택에 대한 경험은 대단히 감사하겠습니다.


16
@Boltbait : 튜플은 set theory en.wikipedia.org/wiki/Tuple
Matthew Whited

16
@BoltBait : "튜플"은 순서가 지정된 값 세트이며 데이터베이스의 행과 관련이있을 필요는 없습니다.
FrustratedWithFormsDesigner

19
좋은 튜플 포장 풀기 작업이 있으면 C #의 튜플이 훨씬 더 좋을 것입니다 :)
Justin

4
@ John Saunders 내 질문은 특히 C #의 디자인 결정에 관한 것입니다. 다른 .net 언어를 사용하지 않으므로 튜플이 어떤 영향을 미치는지 확신 할 수 없습니다. 그래서 나는 그것을 C #으로 표시했습니다. 그것은 나에게 합리적인 것처럼 보였지만 .net으로의 변경도 괜찮습니다.
Jason Webb

13
@ John Saunders : C #으로 작성된 응용 프로그램에서 Tuples를 사용하거나 사용하지 않는 것과 관련된 디자인 결정을 요구하고 있다고 확신합니다. 나는 그가 C # 언어를 만드는 디자인 결정에 대해 묻고 있다고 생각하지 않습니다.
Brett Widmeier 2016 년

답변:


163

튜플은 생성 및 사용을 모두 제어 할 경우 유용합니다. 컨텍스트를 유지 관리 할 수 ​​있으므로 이해해야합니다.

그러나 공용 API에서는 효과가 떨어집니다. 소비자 (귀하가 아닌)는 문서를 추측하거나 찾아야합니다. 특히Tuple<int, int> .

개인 / 내부 회원에게는 사용하지만 공개 / 보호 회원에게는 결과 클래스를 사용합니다.

이 답변 에는 정보가 있습니다.


19
공개 / 비공개 간의 차이는 매우 중요합니다. 퍼블릭 API에서 튜플을 반환하는 것은 실제로 나쁜 생각이지만 내부적으로 사물이 밀접하게 결합되어 있지만 ( 괜찮습니다 ) 괜찮습니다.
클린턴 피어스

36
단단히 결합 또는 단단히 튜플? ;)
contactmatt

적절한 문서가 여기서 유용하지 않을 수 있습니까? 예를 들어, Scala StringOps(기본적으로 Java 용 "확장 메소드"클래스 String)에는 메소드가 있습니다 parition(Char => Boolean): (String, String)(조건 자를 취하고 2 개의 문자열의 튜플을 리턴 함). 출력이 무엇인지 분명합니다 (명확하게 하나는 술어가 참인 문자이고 다른 하나는 거짓 인 자이지만 어느 것이 어느 것인지 명확하지 않습니다). 이것을 정리하는 것은 문서입니다 (그리고 패턴 일치는 어떤 사용법에서 명확하게하기 위해 사용될 수 있습니다).
Kat

@Mike : 그것은 어딘가에 고통을 줄 API의 특징 인 옳고 그름을 얻기가 어렵게 만듭니다 :-)
Bryan Watts

79

내가 보는 방식으로 Tuple은 결과 클래스를 작성하는 지름길입니다 (다른 용도도 있음).

실제로 다른 귀중한 용도가 있습니다 Tuple<> . 대부분 유사한 구조를 공유하는 특정 유형의 그룹의 의미를 추상화하고 단순히 일련의 값으로 취급합니다. 모든 경우에 튜플의 이점은 속성은 노출하지만 메서드는 노출하지 않는 데이터 전용 클래스로 네임 스페이스를 어지럽히 지 않는다는 것입니다.

다음은 합리적으로 사용되는 예입니다 Tuple<>.

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

위 예제에서 우리는 한 쌍의 상대를 나타내려고합니다. 튜플은 새 클래스를 만들지 않고도 이러한 인스턴스를 연결하는 편리한 방법입니다. 또 다른 예는 다음과 같습니다.

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

포커 패는 단순한 카드 세트로 생각할 수 있으며 튜플은 그 개념을 표현하는 합리적인 방법입니다.

Tuples의 요점을 놓칠 가능성을 제쳐두고 Tuple이있는 예는 나쁜 디자인 선택입니까?

Tuple<>퍼블릭 타입의 퍼블릭 API의 일부로 강력한 타입의 인스턴스를 반환하는 것은 좋은 생각이 아닙니다. 본인이 알고 있듯이 튜플을 사용하려면 관련 당사자 (라이브러리 작성자, 라이브러리 사용자)가 사용중인 튜플 유형의 목적과 해석에 대해 미리 동의해야합니다. 직관적이고 명확한 API를 사용하여Tuple<>공개적으로 API의 의도와 행동을 모호하게하는 것만으로 입니다.

익명 형식도 일종의 튜플 이지만 강력하게 형식이 지정되어 있으며 해당 형식에 속하는 속성에 대해 명확하고 유익한 이름을 지정할 수 있습니다. 그러나 익명 유형은 다른 방법으로 사용하기가 어렵습니다. 주로 LINQ와 같은 기술을 지원하기 위해 추가되었습니다. (예, 동일한 유형과 명명 된 속성을 가진 익명 유형이 컴파일러에 의해 통합되어 있음을 알고 있습니다).

내 경험 법칙은 공용 인터페이스에서 반환하는 경우 명명 된 유형으로 만드십시오 .

튜플을 사용하는 또 다른 경험의 규칙은 다음 같습니다. 이름 메서드 인수와 Tuple<>가능한 유형의 localc 변수는 가능한 명확하게-이름이 튜플 요소 간의 관계의 의미를 나타내도록합니다. 내 var opponents = ...예를 생각해보십시오 .

다음 은 내 어셈블리 내에서만 사용 Tuple<>하기 위해 데이터 전용 유형 선언하지 않기 위해 사용한 실제 사례의 예입니다 . 익명 유형을 포함하는 일반 사전을 사용하는 경우 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 사전에서 익명 유형으로 인해 발생하는 문제를 해결하는 또 다른 (간단한) 방법이 있습니다. 즉, var키워드를 사용 하여 컴파일러가 유형을 '유추'할 수 있습니다. 그 버전은 다음과 같습니다.

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

5
@ stakx : 예, 동의합니다. 그러나 명심 - 예는 크게의 사용이 때의 경우를 설명하기위한 것입니다 Tuple<> 이해. 항상 대안이 있습니다 ...
LBushkin

1
TryGetValue 또는 TryParse에서와 같이 매개 변수를 Tuple로 바꾸는 것은 공개 API가 Tuple을 반환하는 것이 합리적 일 수있는 몇 안되는 경우 중 하나라고 생각합니다. 실제로 하나 이상의 .NET 언어가 자동으로이 API를 변경합니다.
Joel Mueller

1
@ stakx : 튜플도 변경할 수 없지만 배열은 변경할 수 없습니다.
Robert Paulson

2
나는 Tuples가 불변 포커 플레이어 객체로만 유용하다는 것을 이해했습니다.
Gennady Vanin Геннадий Ванин

2
+1 큰 대답-나는 실제로 내 마음을 약간 바꾼 두 가지 초기 예를 좋아합니다. 튜플이 적어도 커스텀 구조체 또는 유형만큼 적절한 예제를 본 적이 없습니다. 그러나 나에게 당신의 마지막 "실제 사례"는 더 이상 가치를 추가하지 않는 것 같습니다. 처음 두 예제는 완벽하고 간단합니다. 마지막은 이해하기 조금 어렵고 대체 접근법이 훨씬 간단하고 튜플이 필요하지 않기 때문에 "PS"종류는 쓸모가 없습니다.
chiccodoro

18

튜플은 유용 할 수 있지만 나중에 고통이 될 수도 있습니다. 반환 Tuple<int,string,string,int>하는 메서드가 있다면 나중에 그 값이 무엇인지 어떻게 알 수 있습니까? 그들이 ID, FirstName, LastName, Age거나 그들 UnitNumber, Street, City, ZipCode이었다.


9

튜플은 C # 프로그래머의 관점에서 CLR에 상당히 압도적입니다. 길이가 다양한 항목 모음이 있으면 컴파일시 고유 한 정적 이름을 가질 필요가 없습니다.

그러나 길이가 일정한 컬렉션이있는 경우 컬렉션의 고정 위치마다 각각 미리 정의 된 특정 의미가 있음을 의미합니다. 그리고는 항상 다소의 중요성을 기억하는 것보다, 그 경우에 그들에게 적절한 정적 이름을 지정하는 것이 좋습니다 Item1, Item2

C #의 익명 클래스는 이미 가장 일반적으로 사용되는 튜플 사용에 대한 최상의 솔루션을 제공하며 항목에 의미있는 이름을 지정하므로 실제로 그 점에서 우수합니다. 유일한 문제는 명명 된 메소드에서 유출 될 수 없다는 것입니다. C #에서 튜플을 구체적으로 지원하는 것보다 제한이 해제 된 것 같습니다 (아마도 개인 메서드에만 해당).

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

일반적인 특징으로, 내가보고 싶은 것은 .net이 몇 가지 특수한 종류의 익명 유형에 대한 표준을 struct var SimpleStruct {int x, int y;}정의하는 것 입니다. 예를 들어 간단한 구조체와 관련된 guid로 시작하는 이름으로 구조체를 정의합니다. {System.Int16 x}{System.Int16 y}추가 된 것과 같은 것이 있습니다 . 해당 GUID로 시작하는 이름은 해당 요소와 특정 지정된 내용 만 포함하는 구조체를 나타내야합니다. 동일한 이름에 대한 여러 정의가 범위 내에 있고 일치하면 모두 동일한 유형으로 간주됩니다.
supercat

이러한 것은 변경 가능하고 불변 인 클래스 및 구조체뿐만 아니라 일치하는 구조가 일치하는 의미를 암시하는 것으로 간주되는 상황에서 사용하기위한 인터페이스 및 대리자를 포함하여 몇 가지 유형에 유용합니다. 동일한 매개 변수를 가진 두 개의 델리게이트 유형을 상호 교환 할 수없는 것으로 간주하는 것이 유용한 이유는 확실히 있지만, 메소드가 매개 변수 조합을 취하는 델리게이트를 원하지만 특정 범위를 넘어서는 델리게이트를 원할 경우에도 유용합니다. 어떤 대의원인지는 상관하지 않습니다.
supercat

불행히도 두 명의 다른 사람들이 단일 ref매개 변수 가 필요한 입력 대리자로 사용되는 함수를 작성하려는 경우 두 사람 에게 전달할 수있는 대리자를 가질 수있는 유일한 방법은 한 사람이 생성하고 컴파일하는 경우입니다. 델리게이트 유형을 작성하고 다른 유형으로 빌드합니다. 두 사람이 두 유형을 동의어로 간주해야한다는 것을 나타내는 방법은 없습니다.
supercat

익명 클래스를 사용하는 것보다 더 구체적인 예가 Tuple있습니까? 방금 튜플을 사용하는 코드베이스에서 50 개 장소를 훑어 보았으며 모두 반환 값 (일반적으로 yield return)이거나 다른 곳에서 사용되는 컬렉션 요소이므로 익명 클래스로 이동하지 마십시오.

2
@JonofAllTrades-의견은 아마도 다를 수 있지만, 누군가가 나인 경우 에도 다른 사람이 사용하는 것처럼 공개 방법을 설계하려고합니다 . 그래서 나는 좋은 고객 서비스를 제공하고 있습니다! 함수를 작성하는 것보다 함수를 여러 번 호출하는 경향이 있습니다. :)
Daniel Earwicker

8

keyword var와 유사하게 , 편의를위한 것이지만 쉽게 남용됩니다.

가장 겸손한 견해 Tuple로는, 귀국 수업으로 노출하지 마십시오 . 서비스 또는 구성 요소의 데이터 구조에 필요한 경우 비공개로 사용하지만 공용 메서드에서 잘 구성된 잘 알려진 클래스를 반환하십시오.

// 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
주류 "RAD"언어 (자바가 가장 좋은 예)는 항상 안전을 선택하고 발 유형 시나리오에서 촬영을 피합니다. Microsoft가 C #을 사용하여 기회를 잡고 언어를 잘못 사용할 수 있어도 좋은 힘을주게되어 기쁩니다.
Matt Greer

4
var 키워드는 남용 할 수 없습니다. 아마도 당신은 역동적 인 의미가 있습니까?
Chris Marisic 2016 년

@Chris Marisic은 단지 동일한 시나리오에서 의미하지 않았다는 것을 분명히하기 위해-당신은 절대적으로 정확 var하거나 , 전달되거나 선언 된 범위 밖에 존재할 수 없습니다. 그러나 여전히 의도 된 목적 을 초과 하여 사용하고 "거품"을 사용할 수 있습니다.
johnny g

5
나는 여전히 var가 학대 기간을 남길 수 없다는 것을 주장합니다. 더 짧은 변수 정의를 만드는 것은 키워드 일뿐입니다. 귀하의 주장은 아마도 익명 유형에 관한 것이지만 여전히 정적으로 정적으로 링크 된 유형이기 때문에 실제로 남용 될 수는 없습니다. 동적은 매우 다른 이야기입니다.
Chris Marisic 2016 년

4
var는 남용 될 경우 때때로 코드를 읽는 사람에게 문제를 일으킬 수 있다는 의미에서 남용 될 수 있습니다. 특히 Visual Studio에 있지 않고 인텔리전스가 부족한 경우.
매트 그리어

5

같은 클래스를 사용하는 ResultType것이 더 명확합니다. (튜플로가 호출 될 것입니다 반면에 당신은 클래스의 필드에 의미있는 이름을 부여 할 수 Item1Item2). 두 필드의 유형이 동일한 경우 훨씬 더 중요합니다. 이름이 명확하게 구분됩니다.


하나의 작은 추가 장점 : 클래스의 매개 변수를 안전하게 재정렬 할 수 있습니다. 튜플에 대해 그렇게하면 코드가 손상되고 필드의 유형이 비슷한 경우 컴파일 타임에 감지 할 수 없습니다.

개발자가 의미있는 속성 이름을 그룹화하는 의미있는 클래스 이름을 생각할 힘이 없을 때 Tuples가 사용된다는 데 동의합니다. 프로그래밍은 의사 소통에 관한 것입니다. 튜플은 통신에 대한 반 패턴입니다. 개발자가 좋은 디자인 결정을 내릴 수 있도록 Microsoft가 언어를 사용하지 않는 것을 선호했을 것입니다.
mike gold

5

장식-정렬-장식하지 않은 패턴으로 튜플을 사용하는 것은 어떻습니까? (Perl 사람들을위한 Schwartzian 변환). 여기에 확실한 예가 있지만, Tuples는 이런 종류의 일을 처리하는 좋은 방법 인 것 같습니다.

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

이제 두 요소의 Object [] 또는이 특정 예제에서 두 요소의 문자열 []을 사용할 수있었습니다. 요점은 내부적으로 사용되며 읽기 쉬운 튜플의 두 번째 요소로 무엇이든 사용할 수 있다는 것입니다.


3
생성자 대신 Tuple.Create를 사용할 수 있습니다. 더 짧습니다.
Kugel

익명 형식은 훨씬 더 읽기 쉽습니다. 'x'대신 실제 변수 이름을 사용하는 것처럼
Dave Cousineau

그것은 것 지금 . 그것은 몇 년 전에 게시 된 답변이 결코 새로운 기술을 위해 정리되거나 업데이트되지 않는 SO 문제입니다.
클린턴 피어스

4

IMO이 "튜플"은 기본적으로 이름이없는 멤버를 가진 모든 공용 액세스 익명 struct유형 입니다 .

튜플을 사용 하는 유일한 장소는 매우 제한된 범위에서 일부 데이터를 빠르게 함께 블랍해야 할 때입니다. 데이터의 의미는 분명해야 하므로 코드를 읽기가 어렵지 않습니다. 따라서 (행, 콜)에 튜플 ( int, int)을 사용하는 것이 합리적입니다. 그러나 나는 struct지명 된 회원들과 의 이점을 찾기가 힘듭니다. (실수는 없으며 행 / 열은 실수로 상호 교환되지 않습니다)

발신자에게 데이터를 다시 보내거나 발신자의 데이터를 수락하는 경우 실제로 struct이름이 지정된 멤버와 함께 사용해야합니다 .

간단한 예를 들어 보자.

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

튜플 버전

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

명명 된 멤버가있는 구조체 대신 튜플을 사용하면 이점이 없습니다. 명명되지 않은 멤버를 사용하는 것은 코드의 가독성과 이해를 돕기 위해 한 단계 뒤로 이동합니다.

Tuple struct은 실제 이름이 지정된 멤버로 생성하는 것을 피하는 게으른 방법으로 나를 때립니다 . 튜플을 과도하게 사용하면 실제로 코드를 접하는 사람이 명명 된 멤버 가 필요할 것이라고 생각하는 곳에서 튜플을 남용하면 A Bad Thing ™이 있습니다.


3

나를 판단하지 마십시오. 나는 전문가가 아니지만 C # 7.x의 새로운 Tuples를 사용하면 다음과 같이 반환 할 수 있습니다.

return (string Name1, int Name2)

최소한 지금은 이름을 지정할 수 있으며 개발자는 일부 정보를 볼 수 있습니다.


2

물론입니다! 말했듯이 튜플은 로컬 소비를 위해 일부 항목을 그룹화하려는 경우 코드와 시간을 절약 할 수 있습니다. 또한 구체적인 클래스를 전달할 때보 다 더 일반적인 처리 알고리즘을 만드는 데 사용할 수 있습니다. KeyValuePair 또는 DataRow 이외의 방법으로 한 메소드에서 다른 메소드로 일부 날짜를 신속하게 전달하기를 원하는 횟수를 기억할 수 없습니다.

반면에, 그것을 과도하게 사용하고 튜플을 전달하는 것이 가능합니다. 여러 클래스에서 튜플을 사용하려는 경우 구체적인 클래스 하나를 만드는 것이 좋습니다.

물론 적당히 사용되는 튜플은 더 간결하고 읽기 쉬운 코드로 이어질 수 있습니다. 튜플이 다른 언어로 어떻게 사용되는지에 대한 예는 C ++, STL 및 Boost를 살펴볼 수 있지만 결국에는 .NET 환경에 가장 적합한 방법을 찾기 위해 실험해야합니다.


1

튜플은 .NET 4에서 쓸모없는 프레임 워크 기능입니다. C # 4.0에서는 큰 기회를 놓쳤다 고 생각합니다. 명명 된 멤버와 튜플을 갖고 싶어서 Value1 , Value2 대신 이름으로 튜플의 다양한 필드에 액세스 할 수있었습니다. 등 ...

언어 (구문)를 변경해야했지만 매우 유용했을 것입니다.


튜플은 어떻게 "언어 기능"입니까? 모든 .net 언어에 사용 가능한 클래스가 아닌가요?
Jason Webb

11
아마 C #에는 쓸모가 없습니다. 그러나 System.Tuple은 C #으로 인해 프레임 워크에 추가되지 않았습니다. F #과 다른 언어 간의 상호 운용성을 용이하게하기 위해 추가되었습니다.
Joel Mueller

@ 제이슨 : 언어 기능이라고 말하지 않았습니다 (잘못 입력했지만이 의견을 말하기 전에 수정했습니다).
Philippe Leybaert 2016 년

2
@Jason-튜플을 직접 지원하는 언어는 튜플을 구성 요소 값으로 분해하는 것을 암시 적으로 지원합니다. 이러한 언어로 작성된 코드는 일반적으로 Item1, Item2 속성에 액세스하지 않습니다. let success, value = MethodThatReturnsATuple()
Joel Mueller

@Joel :이 질문은 C #으로 태그되어 있으므로 C #에 관한 것입니다. 나는 그들이 언어에서 일류 기능으로 바꿀 수 있다고 생각합니다.
Philippe Leybaert 2016 년

1

값이 무엇을 나타내는 지 표시하지 않기 때문에 개인적으로 Tuple을 반환 유형으로 사용하지 않습니다. 튜플은 객체와 달리 값 유형이므로 평등을 이해하기 때문에 유용한 용도로 사용됩니다. 이 때문에 다중 변수 키가 필요한 경우 사전 키로 사용하거나 여러 변수로 그룹화하고 중첩 그룹화를 원하지 않는 경우 (내포 그룹화를 원하는 사람은 누구입니까?) 매우 자세한 정보로 문제를 극복하기 위해 도우미 방법으로 문제를 만들 수 있습니다. Item1, Item2 등을 통해 멤버에 자주 액세스하는 경우 구조체 또는 익명 클래스와 같은 다른 구문을 사용해야합니다.


0

나는 모두, 튜플을 사용했습니다 Tuple새로운 ValueTuple다른 시나리오의 숫자에, 다음과 같은 결론에 도달 : 사용하지 마십시오 .

매번 다음과 같은 문제가 발생했습니다.

  • 강력한 이름 지정으로 인해 코드를 읽을 수 없게되었습니다.
  • 기본 클래스 DTO 및 자식 클래스 DTO 등과 같은 클래스 계층 구조 기능을 사용할 수 없습니다.
  • 둘 이상의 장소에서 사용되는 경우 깨끗한 클래스 이름 대신 이러한 추악한 정의를 복사하여 붙여 넣습니다.

내 의견은 튜플은 C #의 기능이 아니라 해롭다는 것입니다.

나는 다소 비슷한,하지만 많은 덜 가혹한 비판 Func<>하고 Action<>. 이것들은 많은 상황, 특히 단순 Action하고 Func<type>변형에 유용 하지만 그 이상으로 델리게이트 유형을 만드는 것이 더 우아하고 읽기 쉽고 유지 관리 가능하며 ref/ out매개 변수 와 같은 더 많은 기능을 제공한다는 것을 알았습니다 .


나는 명명 된 튜플을 언급 ValueTuple했으며-나도 그것을 좋아하지 않습니다. 첫째, 이름은이 중 하나에 암시 적으로 할당 할 수 있기 때문에 엉망으로 매우 쉽게, 더 제안의의 강한되지 않습니다 Tuple또는 ValueTuple같은 번호 및 항목의 종류. 둘째, 상속의 부재와 전체 정의를 복사하여 붙여야 할 필요성은 여전히 ​​훼손입니다.
Mr. TA

나는 그 점에 동의합니다. 생산자와 소비자를 통제 할 때와 너무 멀리 있지 않은 경우에만 Tuples를 사용하려고합니다. 같은 방법으로 의미하는 생산자와 소비자는 '가까운'반면, 다른 어셈블리의 생산자와 소비자는 '광년이 멀다'. 그래서 메소드의 시작 부분에 튜플을 만들고 마지막에 사용하면? 물론 괜찮습니다. 또한 용어 등을 문서화합니다. 그러나 네, 일반적으로 그들이 올바른 선택이 아니라는 데 동의합니다.
Mike Christiansen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.