통일 이란 일반적으로 "컴퓨터 과학 이외의 것"을 "실제로 만들기"를 의미합니다.
프로그래밍 에서 언어 자체의 정보에 액세스 할 수 있으면 무언가가 구체화 됩니다.
C #이 수행하고 구체화하지 않은 제네릭과 관련이없는 두 가지 예를 들어, 메소드와 메모리 액세스를 봅시다.
OO 언어에는 일반적으로 메소드 가 있으며 클래스에 바인딩되지는 않지만 유사한 함수 를 갖지 않는 메소드가 많이 있습니다. 따라서 그러한 언어로 메소드를 정의하고 호출하거나 대체 할 수 있습니다. 이러한 모든 언어를 사용하면 실제로 메소드 자체를 프로그램의 데이터로 처리 할 수 있습니다. C # (및 실제로 C #이 아닌 .NET)을 사용 MethodInfo
하면 메서드를 나타내는 개체를 사용할 수 있으므로 C # 메서드가 구체화됩니다. C #의 메소드는 "퍼스트 클래스 객체"입니다.
모든 실제 언어에는 컴퓨터의 메모리에 액세스 할 수있는 수단이 있습니다. C와 같은 저수준 언어에서는 컴퓨터가 사용하는 숫자 주소 간의 매핑을 직접 처리 할 수 있으므로 이와 같은 방식으로 int* ptr = (int*) 0xA000000; *ptr = 42;
메모리 주소 0xA000000
에 액세스하는 것이 의심 될만한 이유가 있다면 무언가를 날려 버립니다). C #에서는 이것이 합리적이지 않습니다 (우리는 .NET에서 강제 할 수는 있지만 .NET 메모리 관리를 사용하면 유용하지 않을 것입니다). C #에는 통합 메모리 주소가 없습니다.
그래서,로 refied 수단은 "구체화 유형" "진짜을했다"유형 우리가 할 수있는 "이야기"입니다 해당 언어이다.
일반적으로 이것은 두 가지를 의미합니다.
하나는 List<string>
그대로 string
또는 그대로 유형 int
입니다. 해당 유형을 비교하고 이름을 확인한 후 문의 할 수 있습니다.
Console.WriteLine(typeof(List<string>).FullName); // System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
Console.WriteLine(typeof(List<string>) == (42).GetType()); // False
Console.WriteLine(typeof(List<string>) == Enumerable.Range(0, 1).Select(i => i.ToString()).ToList().GetType()); // True
Console.WriteLine(typeof(List<string>).GenericTypeArguments[0] == typeof(string)); // True
그 결과 메소드 자체 내에서 제네릭 메소드 (또는 제네릭 클래스의 메소드) 매개 변수 유형을 "토론"할 수 있습니다.
public static void DescribeType<T>(T element)
{
Console.WriteLine(typeof(T).FullName);
}
public static void Main()
{
DescribeType(42); // System.Int32
DescribeType(42L); // System.Int64
DescribeType(DateTime.UtcNow); // System.DateTime
}
일반적으로이 작업을 너무 많이하는 것은 "취약한"것이지만 많은 유용한 경우가 있습니다. 예를 들어, 다음을보십시오.
public static TSource Min<TSource>(this IEnumerable<TSource> source)
{
if (source == null) throw Error.ArgumentNull("source");
Comparer<TSource> comparer = Comparer<TSource>.Default;
TSource value = default(TSource);
if (value == null)
{
using (IEnumerator<TSource> e = source.GetEnumerator())
{
do
{
if (!e.MoveNext()) return value;
value = e.Current;
} while (value == null);
while (e.MoveNext())
{
TSource x = e.Current;
if (x != null && comparer.Compare(x, value) < 0) value = x;
}
}
}
else
{
using (IEnumerator<TSource> e = source.GetEnumerator())
{
if (!e.MoveNext()) throw Error.NoElements();
value = e.Current;
while (e.MoveNext())
{
TSource x = e.Current;
if (comparer.Compare(x, value) < 0) value = x;
}
}
}
return value;
}
이는 유형 사이의 비교를 많이하지 않는 TSource
다른 행동에 대한 여러 유형의 (모든에서 제네릭을 사용하지 것이 일반적으로 기호)하지만이 될 수 종류의 코드 경로 사이의 분할을한다 null
(반환해야 null
하는 경우 어떤 요소를 발견하고, 비교 요소 중 하나 인 경우 최소 찾을 비교를 안 null
) 및 수없는 유형의 코드 경로 null
에는 요소를 찾을 수없는 경우 throw 할 필요가을 (, 그리고 가능성에 대해 걱정하지 않는 null
요소 ).
때문에 TSource
이 방법에서 "진짜"입니다,이 비교는 런타임 또는 jitting시 중 하나를 만들 수 있습니다 (일반적으로 확실히 위의 경우는 시간을 jitting에서 그렇게 할 것 아닌 경로가 취해지지에 대한 기계 코드를 생성, 시간을 jitting) 그리고 우리는이 각 경우에 대해 별도의 "실제"버전의 방법. (최적화 임에도 불구하고 머신 코드는 다른 참조 유형 유형 매개 변수에 대해 서로 다른 메소드에 대해 공유됩니다. 이는 영향을 미치지 않을 수 있기 때문에 머신 코드의 양을 줄일 수 있습니다).
C #으로 우리가 당연이 구체화을하기 때문에 당신은 또한, 자바와 거래를하지 않는 (그것은 C #에서 일반적인 유형의 구체화에 대해 이야기하는 것이 일반적 아니라, 모든 유형의 구체화되는 자바가 아닌 일반적인 유형이라고합니다. 구체화 그 때문에 그들과 일반 유형의 차이입니다).