C# 제네릭의 "기본"유형 매개 변수에 대한 합리적인 접근 방식이 있습니까?
-
22-08-2019 - |
문제
C ++ 템플릿에서 특정 유형 매개 변수가 기본값임을 지정할 수 있습니다. 즉 명시 적으로 지정되지 않으면 T 형을 사용합니다.
C#에서 수행하거나 근사 할 수 있습니까?
나는 다음과 같은 것을 찾고 있습니다.
public class MyTemplate<T1, T2=string> {}
따라서 명시 적으로 지정하지 않는 유형의 인스턴스 T2
:
MyTemplate<int> t = new MyTemplate<int>();
본질적으로 :
MyTemplate<int, string> t = new MyTemplate<int, string>();
궁극적으로 나는 상당히 널리 사용되는 템플릿이있는 경우를보고 있지만 추가 유형 매개 변수로 확장을 고려하고 있습니다. 나는 서브 클래스를 할 수 있다고 생각하지만,이 정맥에 다른 옵션이 있는지 궁금했다.
해결책
서브 클래싱이 최선의 선택입니다.
나는 당신의 주요 제네릭 클래스를 서브 클래스합니다.
class BaseGeneric<T,U>
특정 수업으로
class MyGeneric<T> : BaseGeneric<T, string>
이를 통해 논리를 한 곳 (기본 클래스)으로 쉽게 유지할 수 있지만 두 가지 사용 옵션을 모두 쉽게 제공 할 수 있습니다. 수업에 따라, 이런 일을하기 위해 필요한 추가 작업은 거의 없을 것입니다.
다른 팁
하나의 솔루션은 서브 클래싱입니다. 내가 대신 사용하는 또 다른 것은 공장 방법입니다 (VAR 키워드와 결합).
public class MyTemplate<T1,T2>
{
public MyTemplate(..args..) { ... } // constructor
}
public static class MyTemplate{
public static MyTemplate<T1,T2> Create<T1,T2>(..args..)
{
return new MyTemplate<T1, T2>(... params ...);
}
public static MyTemplate<T1, string> Create<T1>(...args...)
{
return new MyTemplate<T1, string>(... params ...);
}
}
var val1 = MyTemplate.Create<int,decimal>();
var val2 = MyTemplate.Create<int>();
위의 예에서 val2
유형입니다 MyTemplate<int,string>
그리고 아닙니다 그것에서 파생 된 유형.
유형 class MyStringTemplate<T>:MyTemplate<T,string>
같은 유형이 아닙니다 MyTemplate<T,string>
. 이것은 특정 시나리오에서 몇 가지 문제를 일으킬 수 있습니다. 예를 들어 인스턴스를 캐스트 할 수 없습니다 MyTemplate<T,string>
에게 MyStringTemplate<T>
.
그렇게 클래스 오버로드를 만들 수도 있습니다
public class MyTemplate<T1, T2> {
public T1 Prop1 { get; set; }
public T2 Prop2 { get; set; }
}
public class MyTemplate<T1> : MyTemplate<T1, string>{}
C#은 그러한 기능을 지원하지 않습니다.
당신이 말했듯이, 당신은 그것을 서브 클래스 할 수 있지만 (밀봉되지 않은 경우, 모든 생성자 선언을 복제 할 수 있지만) 완전히 다른 것입니다.
불행히도 C#은 당신이하려는 일을 지원하지 않습니다. 매개 변수의 기본 유형이 일반적인 제약 조건을 준수해야하며 CLR이 유형 안전성을 보장하려고 할 때 두통을 생성 할 가능성이 높다는 점을 감안할 때 구현하기 어려운 기능입니다.