이 질문만큼 오래된 것은 위의 설명에서 여전히 임의의 공감대를 얻습니다. 설명은 여전히 완벽하게 잘 유지되지만, 나는 유니온 타입 (C #에서 직접 지원하지 않는 질문에 대한 강력한 형식의 답변) 대신 나에게 도움이되는 유형으로 두 번째로 대답 할 것입니다. ).
using System;
using System.Diagnostics;
namespace Union {
[DebuggerDisplay("{currType}: {ToString()}")]
public struct Either<TP, TA> {
enum CurrType {
Neither = 0,
Primary,
Alternate,
}
private readonly CurrType currType;
private readonly TP primary;
private readonly TA alternate;
public bool IsNeither => currType == CurrType.Primary;
public bool IsPrimary => currType == CurrType.Primary;
public bool IsAlternate => currType == CurrType.Alternate;
public static implicit operator Either<TP, TA>(TP val) => new Either<TP, TA>(val);
public static implicit operator Either<TP, TA>(TA val) => new Either<TP, TA>(val);
public static implicit operator TP(Either<TP, TA> @this) => @this.Primary;
public static implicit operator TA(Either<TP, TA> @this) => @this.Alternate;
public override string ToString() {
string description = IsNeither ? "" :
$": {(IsPrimary ? typeof(TP).Name : typeof(TA).Name)}";
return $"{currType.ToString("")}{description}";
}
public Either(TP val) {
currType = CurrType.Primary;
primary = val;
alternate = default(TA);
}
public Either(TA val) {
currType = CurrType.Alternate;
alternate = val;
primary = default(TP);
}
public TP Primary {
get {
Validate(CurrType.Primary);
return primary;
}
}
public TA Alternate {
get {
Validate(CurrType.Alternate);
return alternate;
}
}
private void Validate(CurrType desiredType) {
if (desiredType != currType) {
throw new InvalidOperationException($"Attempting to get {desiredType} when {currType} is set");
}
}
}
}
상기 클래스가 될 수있는 형식 나타내는 하나 TP 또는 TA를. 당신은 그것을 그대로 사용할 수 있습니다 (유형은 원래의 대답으로 되돌아갑니다) :
// ...
public static Either<FishingBot, ConcreteMixer> DemoFunc(Either<JumpRope, PiCalculator> arg) {
if (arg.IsPrimary) {
return new FishingBot(arg.Primary);
}
return new ConcreteMixer(arg.Secondary);
}
// elsewhere:
var fishBotOrConcreteMixer = DemoFunc(new JumpRope());
var fishBotOrConcreteMixer = DemoFunc(new PiCalculator());
중요 사항 :
- 확인하지 않으면 런타임 오류가 발생합니다
IsPrimary
먼저 .
IsNeither
IsPrimary
또는 중 하나를 확인할 수 있습니다 IsAlternate
.
- 당신은 통해 값에 액세스 할 수 있습니다
Primary
및Alternate
- TP / TA와 둘 사이에 암시 적 변환기가있어 값이나
Either
예상되는 위치 를 전달할 수 있습니다 . 당신 이 통과하면Either
곳 TA
이상이 TP
예상된다하지만,이 Either
값의 잘못된 유형을 포함하면 런타임 오류가 발생합니다.
나는 일반적으로 메소드가 결과 또는 오류를 반환하기를 원할 때 이것을 사용합니다. 실제로 해당 스타일 코드를 정리합니다. 나는 또한 메소드 오버로드를 대신하여 이것을 거의 사용 하지 않는 경우도있다 . 실제로 이것은 과부하를 대체하기에 매우 열악합니다.