사용 시기: 튜플 대 클래스 c# 7.0
튜플을 사용하기 전에는 class
변수를 생성하고 이 클래스에서 객체를 생성하고 해당 객체를 일부 함수의 반환 유형 으로 만드는 데 사용했습니다 .
이제 튜플을 사용하여 동일한 작업을 수행할 수 있으며 C# 7.0에서는 튜플 속성에 대해 이해할 수 있는 이름을 할당할 수 있습니다(이전 item1
에는 item2
, 등).
이제 언제 튜플을 사용해야 하고 언제 C# 7.0에서 클래스를 만들어야 하는지 궁금합니다.
이 답변이 여기 일부 사람들 사이에 약간의 혼란을 야기하기 때문에 여기서 "튜플"에 대한 모든 참조 ValueTuple
는 C# 7 의 유형 및 새로운 튜플 구문 설탕 기능을 참조하며 이전 항목을 참조하지 않는다는 점을 명확히 해야 합니다. System.Tuple
참조 유형.
이제 언제 튜플을 사용해야 하고 언제 C# 7.0에서 클래스를 만들어야 하는지 궁금합니다.
그것은 당신의 코드에 달려 있기 때문에 당신만이 그 질문에 정말로 대답할 수 있습니다.
그러나 다음과 같은 지침과 규칙을 선택할 때 따를 수 있는 지침과 규칙이 있습니다.
튜플은 값이므로 참조가 아닌 값으로 복사됩니다.
대부분의 경우 이것은 문제가 되지 않습니다. 그러나 큰 구조체의 튜플을 전달하는 경우 성능에 영향을 줄 수 있습니다. 그러나 참조 지역/반환을 사용하여 이러한 성능 문제를 해결할 수 있습니다.
또한 값이기 때문에 원격으로 복사본을 수정해도 원본 복사본은 변경되지 않습니다. 이것은 좋은 일이지만 일부 사람들을 잡을 수 있습니다.
튜플 요소 이름은 지속되지 않습니다.
요소에 지정된 이름은 컴파일러에서 사용되며 (대부분의 경우) 런타임에는 사용할 수 없습니다. 이는 리플렉션을 사용하여 이름을 찾을 수 없음을 의미합니다. 동적으로 액세스할 수 없으며 면도기 보기에서 사용할 수 없습니다.
또한 이것은 API에서 중요한 고려 사항입니다. 메서드에서 반환된 튜플은 컴파일 후 이름 검색 가능성에 관한 규칙의 예외입니다. 컴파일러는 튜플 이름에 대한 정보를 보유하는 속성을 메서드에 추가합니다. 즉, 한 어셈블리의 공용 메서드에서 튜플을 안전하게 반환하고 다른 어셈블리의 이름에 액세스할 수 있습니다.
튜플은 가볍다
튜플은 덜 장황하고 선언을 "인라인"(즉, 사용 지점에서 선언)할 수 있으므로 유형보다 작성하기가 훨씬 간단합니다. 이는 예를 들어 여러 값을 반환하는 메서드를 선언할 때 잘 작동합니다.
그러나 사용 지점에서 선언되기 때문에 MethodA
호출 MethodB
하는 호출이 MethodC
있고 각각이 튜플을 반환하는 경우 모든 단계에서 튜플을 재정의해야 합니다. 튜플의 별칭을 만들고 여러 메서드에서 재사용하는 방법은 ( 아직 ) 없습니다 .
상식적으로만 사용하세요
튜플 사용을 고려할 수 있는 모든 상황에서: "튜플이 여기에서 코드를 단순화할 것인가"라는 질문을 스스로에게 하십시오. 대답이 "예"이면 하나를 사용하십시오. 그리고 그것은 궁극적으로 튜플을 사용할지 사용자 정의 클래스를 사용할지에 대한 주요 고려 사항입니다.
일반적으로 명명된 클래스는 시스템 설계에서 어느 정도 의미가 있습니다. 그들은 또한 쓰기에 더 장황합니다. 예를 들어 라는 클래스가 있을 수 있습니다 MediaFileOpener
. 이 클래스가 무엇을 하는지 아는 것이 디자인에 중요합니다. 우리는 미디어 파일로 작업합니다!
익명 유형 및 튜플은 설계상의 중요성이 없고 정보를 이동하기 위한 경량 DTO(Data Transfer Object)만 원하는 경우에 사용됩니다.
일반적으로 클래스에서 클래스의 용도를 설명하는 문서가 필요하거나 클래스에서 제공하는 동작이 있는 경우 전체 클래스를 사용합니다. 임시 저장소 또는 일종의 그룹화가 필요한 경우 Tuple을 사용하십시오. 비동기 메서드에서 둘 이상의 값을 반환하려는 상황을 고려하십시오. Tuple은 그 문제를 해결하기 위해 설계되었습니다.
클래스 사용
개체가 응용 프로그램 전체에서 널리 사용되는 엔터티이고 관계형 데이터베이스(SQL Server, MySQL, SQLite), NoSQL 데이터베이스 또는 캐시(Redis, Azure DocumentDB) 또는 단순 저장소와 같은 일종의 영구 저장소에도 저장되는 경우 텍스트 파일 또는 CSV.
예, 영속적인 것은 자체 클래스가 있어야 합니다.
튜플 사용
귀하의 객체가 귀하의 애플리케이션에 대한 특별한 의미 없이 수명이 짧은 경우. 예를 들어 좌표 쌍을 빠르게 반환해야 하는 경우 다음과 같은 것이 좋습니다.
(double Latitude, double Longitude) getCoordinates()
{
return (144.93525, -98.356346);
}
별도의 클래스를 정의하는 것보다
class Coordinates
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
Tuple은 new
이러한 간단한 작업 을 위해 힙에 메모리를 할당하지 않아도 되는 시간을 절약해 줍니다.
튜플이 유용하다고 생각하는 또 다른 경우는 일부 피연산자에 대해 여러 수학 연산을 수행할 때입니다.
(double Result1, double Result2, double Result3) performCalculations(int operand1, int operand 2)
이 경우 클래스를 정의하는 것은 의미가 없습니다. 계산이 무엇이든 결과는 클래스에 속하지 않습니다. 따라서 대안은 out
변수 를 사용하는 것이지만 튜플이 더 표현력이 뛰어나고 가독성이 향상된다고 생각합니다.
C#이 이미 익명 유형을 지원한다는 점을 언급하는 것으로 시작하고 싶습니다 . 참조 유형입니다. 따라서 명명된 클래스를 만드는 것에 대한 적절한 대안이 이미 있습니다.
명명된 클래스의 한 가지 장점은 재사용(예: 여러 위치에서 동일한 유형이 필요한 경우) 및 문서화하기가 더 쉽다는 것입니다. 익명 유형은 익명이므로 var
익명 유형이 유용한 컨텍스트를 제한하는 를 사용할 수 있는 경우에만 이에 유형화된 변수를 가져올 수 있습니다 (예: 필드 유형, 반환 유형 또는 매개변수 유형으로 사용할 수 없음). .
물론 System.Tuple
. 이는 참조 유형이기도 하며 명시적으로 사용할 수 있습니다. 단점은 멤버에 대한 사용자 정의 이름이 없다는 것입니다.
C# 7 튜플( ValueTuple
)은 익명 형식과 유사한 것으로 간주될 수 있습니다. 첫 번째 차이점은 값 유형이라는 것입니다. 이는 이러한 튜플이 로컬 범위에 있거나 스택을 가로질러 이동하는 한 성능상의 이점이 있음을 의미합니다(이는 제한으로 인해 익명 형식이 일반적으로 사용됨).
두 번째 차이점은 새 구문을 사용하면 튜플이 익명 유형보다 더 많은 위치에 나타날 수 있다는 것입니다. 아시다시피 반환 유형을 정의하는 구문 설탕이 있습니다 ValueTuple
( 반환해야 하는 익명 유형을 사용하는 동안 object
).
세 번째 차이점은 ValueTuple
기본적으로 해체 를 지원 한다는 것입니다. C# 7.0의 새로운 기능 을 인용하려면 :
튜플을 사용하는 또 다른 방법은 튜플을 분해하는 것입니다. 분해 선언은 튜플(또는 다른 값)을 부분으로 분할하고 해당 부분을 개별적으로 새로운 변수에 할당하는 구문입니다.
(string first, string middle, string last) = LookupName(id1); // deconstructing declaration WriteLine($"found {first} {last}.");
Deconstruct 메소드 를 추가하여 사용자 정의 유형으로 할 수도 있습니다 .
초록의 경우:
ValueTuple
가독성을 위해 고려해야 하는 C# 7.0의 구문 설탕이 있습니다.ValueTuple
값 유형입니다. 의 사용class
과struct
적용 사이의 모든 장단점 .ValueTuple
명시 적으로 (구문 설탕의 유무에 관계없이) 사용되어System.Tuple
명명 된 구성원을 유지하면서 다용도성을 가질 수 있습니다 .ValueTuple
해체를 지원합니다.
그것의 필수가 구문 설탕이라는 점을 감안할 때, 선택에 대한 더 강력한 주장은 선택 ValueTuple
하는 것과 동일한 주장 이라고 말하고 싶습니다 struct
. 이는 주로 스택에 있는 작고 변경할 수 없는 유형에 이상적입니다(따라서 boxing 및 unboxing이 많지 않음).
ValueTuple
완전한 구조와 비교 하여 구문 설탕을 고려하면 명시적인 레이아웃 이 필요하거나 여기에 메서드를 추가 ValueTuple
해야 하는 경우가 아니면 기본적 으로 사용 하는 것이 좋습니다 .
또한 구문 설탕이 반드시 가독성을 향상시키는 것은 아니라고 말하고 싶습니다. 주된 이유는 유형의 이름을 지정하지 않고 유형의 이름이 코드에 의미를 제공하기 때문입니다. 그 외에도 이해를 돕기 위해 struct
또는 class
선언에 문서를 추가할 수 있습니다 .
결국 ValueTuple
정말 빛나는 상황 은 메서드에서 여러 값을 반환하는 것입니다. 이 경우 새 out
매개변수 를 생성할 필요가 없습니다 . 그리고 ValueTuple
사용된 문서는 방법의 문서에서 살 수 있습니다. ValueTuple
(예를 들어 확장 메서드 정의) 다른 작업을 수행해야 하는 경우 대신 명명된 형식을 만드는 것이 좋습니다.
튜플은 메서드가 여러 값을 반환하려는 경우와 같이 여러 값을 나타내기 위한 것입니다. C# 7 의 튜플 지원 은 System.ValueTuple<...>
인스턴스를 사용 하여 해당 값 집합을 나타냅니다. 이러한 값의 이름은 해당 값이 사용 중이고 적용되지 않는 컨텍스트에서만 유효합니다.
클래스는 여러 속성을 가진 단일 값을 나타내기 위한 것입니다.
일반적으로 객체가 다른 곳에서 사용될 때 또는 실제 객체 또는 도메인의 개념을 나타내는 경우 클래스를 갖고 싶어합니다. 아마도 튜플이 아닌 자동차나 자동차 매장을 나타내는 클래스를 만들 것입니다.
반면에 메서드에서 몇 개의 개체를 반환하려는 경우가 있습니다. 특별한 것을 나타내지 않을 수도 있습니다. 단지 특정 메서드에서 함께 반환해야 하기 때문입니다. 때로는 도메인의 개념을 나타내더라도(예: 반환 (Car, Store)
하는 Sale
개체 로 표시될 수 있음 ) 실제로 아무데도 사용하지 않고 데이터를 이동하는 것입니다. 이러한 경우 튜플을 사용하는 것이 좋습니다.
이제 C#에 대해 구체적으로 말하면 한 가지 더 알아야 할 사항이 있습니다. C# 7의 튜플 유형은 실제로 ValueTuple
구조체인 입니다. 참조 유형인 클래스와 달리 구조체는 값 유형입니다. 자세한 내용은 msdn 에서 읽을 수 있습니다 . 가장 중요한 것은 많은 복사가 포함될 수 있으므로 주의해야 합니다.
Tuple은 사용자 정의 클래스를 생성하지 않고 여러 값(다른 유형일 수 있음)을 하나의 객체로 결합하려는 경우에 훌륭한 옵션입니다. 이 경우 Tuple은 빠르고 완벽한 옵션입니다.
많이 받는 질문이 될 것 같아요. 현재로서는 새로운 가치 튜플과 클래스를 언제 사용할지에 대한 "모범 사례"가 없습니다.
However, it's worth reading what came up during previous conversations about the previous versions of tuples vs a class.
In my opinion the value tuple should only be used minimally and with no more than a maximum of three values. I think this strikes a good balance of "returning some values without the need for a class" and "horrific mess of values". If you have more than three values to return, make a class.
I'd also never use a tuple to return from a public facing API that consumers will have to use. Again, just use a class.
Here's some real world code that I've used:
public async Task<(double temperature, double humidity, string description)> DownloadTodaysForecast()
As soon as I want to return more complex data, I make a class.
I would avoid using tuples as a return-type of public methods. In such cases I'd prefer to define a class or struct.
ReferenceURL : https://stackoverflow.com/questions/44650636/when-to-use-tuple-vs-class-c-sharp-7-0
'IT이야기' 카테고리의 다른 글
문자열의 차이점 (0) | 2021.10.23 |
---|---|
IdentityServer 흐름 (0) | 2021.10.23 |
C#용 린트 (0) | 2021.10.22 |
Rails의 모델에 대한 외래 키 관계 정의 (0) | 2021.10.22 |
ReSharper - Microsoft.Contracts 사용 시 Null 할당 가능 (0) | 2021.10.22 |