Generics 5에 연결
20.8 표현식 및 명령문
generics에 맞게 일부 표현식 및 명령문의 작동이 수정되었습니다. 이 섹션에서는 이러한 변경 사항을 설명합니다.
20.8.1 기본값 표현식
기본값 표현식은 유형의 기본값을 얻는 데 사용됩니다(§5.2). 일반적으로 유형 매개변수에는 기본값 표현식이 사용됩니다. 유형 매개변수가 값 유형이거나 참조 유형인 경우 아직 존재하지 않을 수 있기 때문입니다. (널 유형에서 유형 매개변수로의 변환은 없습니다.)
primary-no-array-creation-expression:(基本无数组创建表达式:) … default-value-expression(默认值表达式) default-value-expression:(默认值表达式:) primary-expression . default (基本表达式 .default) predefined-type . default(预定义类型. default)
기본값 표현식에 기본 표현식이 사용되고 기본 표현식을 유형으로 나눌 수 없는 경우 컴파일 타임 오류가 발생합니다. 그러나 §7.5.4.1에 설명된 규칙은 E.default를 구성하는 구성 요소에도 적용됩니다.
기본값 표현식의 왼쪽이 런타임 시 참조 유형에 대해 평가되는 경우 결과는 해당 유형으로 null로 변환됩니다. 기본값 표현식의 왼쪽이 런타임 시 값 유형에 대해 평가되는 경우 결과는 값 유형의 기본값(§4.1.2)입니다.
유형이 참조 유형이거나 클래스 제약 조건이 있는 유형 매개변수인 경우 기본값 표현식은 상수 표현식(§7.15)입니다. 또한 유형이 sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double,decimal 또는 bool 중 하나인 경우 기본값 표현식은 상수 표현식입니다.
20.8.2 객체 생성 표현식
객체의 공통 표현식 유형은 유형 매개변수일 수 있습니다. 객체 생성 표현식에서 타입 매개변수를 타입으로 지정하는 경우, 다음 두 가지 조건을 만족해야 하며, 그렇지 않으면 컴파일 타임 오류가 발생합니다
실제 매개변수 목록을 삭제해야 합니다
지정해야 합니다 유형 매개변수 생성자 제약 조건의 경우 new()
유형 매개변수가 바인딩된 런타임 유형의 인스턴스를 생성하고 해당 유형의 기본 생성자를 호출하여 객체 생성 표현식을 실행합니다. 런타임 유형은 참조 또는 값 유형일 수 있습니다.
20.8.3 연산자 유형
typeof 연산자를 유형 매개변수로 사용할 수 있습니다. 결과는 유형 매개변수에 바인딩된 런타임 유형의 System.Type 개체입니다. typeof 연산자를 사용하여 유형을 구성할 수도 있습니다.
class X <T> { public static void PrintTypes() { Console.WriteLine(typeof(T).FullName); Console.WriteLine(typeof(X<X<T>>).FullName); } } class M { static void Main() { X<int>.PrintTypes(); } }
이전 프로그램은 다음과 같이 인쇄됩니다.
System.Int32 X<X<Sytem.Int32>> Typeof运算符不能用于没有指定类型实参的泛型类型声明的名字。 class X<T>{…} class M { static void Main() { Type t = typeof(X); //错误,X需要类型实参 } }
20.8.4 참조 동등 연산자
T가 클래스 제약 조건에 의해 제한되는 경우 참조 유형 동등 연산자를 사용하여 해당 유형의 값을 비교할 수 있습니다. 매개변수 T.
참조 유형 동등 연산자를 사용하면 T에 클래스 제약 조건이 없더라도 유형 매개변수 T의 실제 매개변수를 null인 다른 실제 매개변수와 쉽게 비교할 수 있습니다. 런타임 시 T가 값 유형인 경우 비교 결과는 false입니다.
다음 예에서는 제약이 없는 유형 매개변수 유형의 실제 매개변수가 null인지 확인합니다.
class C<T> { void F(T x) { if(x==null) thow new ArgumentNullException(); … } }
T가 값 유형을 나타낼 수 있더라도 x==null 구문은 허용되며, T가 값 유형인 경우 그 결과는 단순히 false로 정의됩니다.
20.8.5 is运算符
在开放类型上的is运算符操作遵循通常的规则(§7.9.9)。如果e或T的编译时类型是一个开放类型,那么在运行时对于e和T将总是执行动态类型检查。
20.8.6as运算符
只要T有一个类约束,类型参数T可被用在as运算符的右边。这种限制是需要的,因为值null可能被作为运算符的结果返回。
class X { public T F<T>(object o) where T:Attribute { return o as T; //ok,T有一个类约束 } public T G<T>(object o) { return o as T; //错误,T没有约束 }
}
在as运算符(§7.9.10)的当前规范中,对于表达式e as T最后一点表明,如果从e的编译时类型到T,不存在有效的显式引用转换,将会出现编译时错误。对于泛型,这条规则稍微作了修改。如果E的编译时类型或T是一个开放类型,在这种情况下将不会出现编译时错误;相反,运行时检查将会执行。
20.8.7异常语句
对于开放类型,throw(§8.9.5)和try(§8.10)的通常规则是适用的。
只要类型参数具有System.Exeption异常(或子类具有)作为类约束,那么throw语句可以被用作其类型有一个类型参数给定的表达式。
只要类型参数System.Exception(或子类子类具有)作为类约束,那么在catch语句中的命名的类型可能是一个类型参数。
20.8.8 lock语句
lock语句可以被用作其类型由一个类型参数给定的表达式。如果表达式的运行时类型是一个值类型,lock将没有效果(因为对于装箱值不能有任何其他的引用)。
20.8.9 using 语句
using 语句(§8.13)遵循通常的规则:表达式必须被隐式的转换到System.IDisposable。如果类型参数通过System.IDisposable而约束,那么该类型的表达式可以使用using 语句。
20.8.10 foreach语句
给定如下形式的foreach语句
foreach(ElementType element in collection) statement
如果集合表达式是一个没有实现集合模式的类型,但为每个类型T实现了构造接口System.Collections.Generic.IEnumerable8742468051c85b06f0a0af9e3e506b5c,那么foreach语句的扩展是
IEnumerator<T> enumerator = ((IEnuemrable<T>)(collection).GetEnumerator(); try { where (enumerator.MoveNext()){ ElementType element = (ElementType)enumerator.Current; statement; } } finally{ enumerator.Dispose(); }
20.9查找规则修订
泛型修改了用于查找和绑定名字的某些基本规则。下面几节在考虑泛型的情况下,重新叙述了所有的基本名字查找规则。
20.9.1命名空间和类型名字
다음 내용은 §3.8을 대체할 수 있습니다.
C# 프로그램에는 네임스페이스나 유형 이름을 지정해야 하는 여러 컨텍스트가 있습니다. 모든 형태의 이름은 "." 표시로 구분된 하나 이상의 식별자로 구성될 수 있습니다.
namespace-name: (네임스페이스 이름:)
namespace-or-type-name (네임스페이스 또는 유형 이름)
type-name: (유형 이름:)
namespace-or-type -name (네임스페이스 또는 유형 이름)
namespace-or-type-name: (네임스페이스 또는 유형 이름:)
identifier type-argument-list opt (식별자 유형 인수 목록 선택 사항)
namespace-or- type-name .identifier type-argument-list opt (네임스페이스 또는 유형 이름. 식별자 유형 인수 목록 선택 사항)
네임스페이스 이름은 네임스페이스(namespace-or-type-)를 참조하는 네임스페이스 이름 또는 유형 이름입니다. 이름). 아래 설명된 결정을 참조하세요. 네임스페이스 이름의 네임스페이스 또는 형식 이름은 네임스페이스를 참조해야 합니다. 그렇지 않으면 컴파일 시간 오류가 발생합니다. 네임스페이스 이름에는 형식 인수가 있을 수 없습니다. 형식만 형식 인수를 가질 수 있습니다.
유형 이름은 유형을 참조하는 네임스페이스 또는 유형 이름입니다. 아래에 설명된 결정을 참조하세요. 유형 이름의 네임스페이스 또는 유형 이름은 유형을 참조해야 합니다. 그렇지 않으면 컴파일 시간 오류가 발생합니다.
네임스페이스나 유형 이름의 의미는 다음과 같이 결정됩니다.
네임스페이스 또는 유형 이름이 I 또는 If53db7e3537772cbf9ba1634d2b17fe6 형식인 경우, 여기서 I는 단일 식별자이고 f53db7e3537772cbf9ba1634d2b17fe6은 선택적 유형 인수 목록입니다.
- 네임스페이스 또는 유형 이름이 제네릭 메서드 선언 내에 나타나고 해당 선언에 지정된 유형 인수 목록 없이 I라는 유형 매개 변수가 포함되어 있는 경우 네임스페이스 또는 유형 이름은 유형 매개 변수를 참조합니다.
- 그렇지 않고 네임스페이스 또는 유형 이름이 유형 선언 내에 나타나는 경우 유형 T(f53db7e3537772cbf9ba1634d2b17fe620.1.2)의 각 인스턴스에 대해 해당 유형 선언의 인스턴스 유형으로 시작하고 각 둘러싸는 클래스 또는 구조체 유형 선언(있는 경우)으로 계속됩니다.
u I가 지정한 이름을 포함하는 유형 매개변수 T의 선언이 지정되지 않고 유형 인수 목록이 없는 경우 네임스페이스 또는 유형 이름은 해당 유형을 참조합니다. 매개변수.
u 그렇지 않고 I가 T의 액세스 가능한 멤버의 이름이고 해당 멤버가 일치하는 수의 유형 매개변수를 가진 유형인 경우 네임스페이스 또는 유형 이름은 T.I 유형을 참조하거나 T .I
u 그렇지 않고 I가 일치하는 수의 유형 인수를 가진 N에서 액세스 가능한 유형의 이름인 경우 네임스페이스 또는 유형 이름은 주어진 유형 인수로 구성된 유형을 참조합니다.
u 그렇지 않고 네임스페이스 또는 유형 이름이 N의 네임스페이스 선언으로 둘러싸인 위치에 나타나는 경우
- 네임스페이스 선언에 I가 지정한 이름의 using alias 지시문이 포함되어 있고 가져오기 이름 공간이 있는 경우 또는 유형이고 인수 목록이 지정되지 않은 경우 네임스페이스 또는 유형 이름은 해당 네임스페이스 또는 유형
을 참조합니다. 그렇지 않으면 네임스페이스 선언의 using 네임스페이스 지시문으로 가져온 네임스페이스에 I가 지정된 네임스페이스가 포함된 경우 A 유형 매개변수의 수와 일치하는 명명된 유형인 경우 네임스페이스 또는 유형 이름은 지정된 유형 인수로 구성된 유형을 참조합니다. - 그렇지 않으면 네임스페이스 또는 유형 이름이 정의되지 않고 컴파일 시간 오류가 발생합니다.
l 그렇지 않은 경우 네임스페이스 또는 유형 이름은 N.I 또는 N.If53db7e3537772cbf9ba1634d2b17fe6 형식입니다. 여기서 N은 네임스페이스 또는 유형 이름이고 I는 식별자이며 < ;A1,…,AN>은 선택적 유형 인수 목록입니다. N은 먼저 네임스페이스 또는 유형 이름으로 결정됩니다. N의 결정이 실패하면 컴파일 타임 오류가 발생합니다. 그렇지 않으면 N.I 또는 N.I
- N이 네임스페이스를 참조하고 I가 N에 포함된 네임스페이스 이름이고 형식 인수 목록이 지정되지 않은 경우 네임스페이스 또는 형식 이름은 포함된 네임스페이스를 참조합니다.
- 그렇지 않고 N이 네임스페이스를 참조하고 I가 일치하는 수의 형식 인수를 사용하여 N에서 액세스할 수 있는 형식의 이름인 경우 네임스페이스 또는 형식 이름은 지정된 형식 인수에서 생성된 형식을 참조합니다.
- 그렇지 않고 N이 클래스 또는 구조체 유형을 참조하고 I가 일치하는 유형 매개변수와 함께 N에 포함된 액세스 가능한 유형의 이름인 경우 네임스페이스 또는 유형 이름 참조는 지정된 인수 해당 유형으로 구성됩니다.
- 그렇지 않으면 N.I는 유효하지 않은 네임스페이스 이름이며 컴파일 타임 오류가 발생합니다.
20.9.2 멤버조회
다음 내용은 대체 가능 §7.3
멤버조회는 문맥상 의미에 따라 타입을 결정하는 과정이다. 식 내에서 멤버 조회는 간단한 이름 평가 또는 멤버 액세스(§20.9.4)로 발생할 수 있습니다.
T 유형의 N이라는 이름의 회원 검색은 다음 규칙에 따라 결정됩니다.
먼저 N이라는 접근 가능한 멤버 집합이 결정됩니다.
- T가 유형 매개변수인 경우 T의 클래스 제약조건 또는 인터페이스 제약조건으로 지정된 각 유형에서 객체의 명명된 N 멤버 집합과 함께 이 집합은 연합의 액세스 멤버로 명명됩니다. .
- 그렇지 않은 경우 이 집합은 상속된 멤버와 개체의 N의 명명된 액세스 가능한 멤버를 포함하여 T의 명명된 액세스 가능한 모든 멤버로 구성됩니다. T가 생성된 유형인 경우 §20.5.4에 설명된 대로 유형 인수를 대체하여 멤버 집합을 얻습니다. 재정의 수정자를 포함한 멤버는 컬렉션에서 삭제됩니다.
다른 멤버에게 숨겨진 멤버는 세트에서 제외됩니다. S가 M이 선언된 유형인 집합의 각 멤버 S.M에 대해 다음 규칙이 적용됩니다.
- M이 상수, 필드, 속성, 이벤트 또는 열거형 멤버인 경우 모든 멤버 S의 기본 클래스에 선언된 항목은 이 컬렉션에서 제거됩니다.
- M이 유형 선언인 경우 S의 기본 클래스에 있는 모든 비유형 선언은 세트에서 제거되고 기본 유형에 선언된 S와 동일한 수의 유형 매개변수를 가진 M의 모든 유형 선언은 컬렉션에서 제거됩니다.
- M이 메소드인 경우 S의 기본 클래스에 선언된 메소드가 아닌 모든 멤버는 이 세트에서 제거되고 S와 기본 유형에 선언된 M의 동일한 시그니처가 있는 모든 메소드는 세트에서 제거됩니다. 이 컬렉션.
다음으로 클래스 멤버를 통해 숨겨진 인터페이스 멤버를 컬렉션에서 제거합니다. 이 단계는 T가 유형 매개변수이고 T에 클래스 제약 조건과 다중 인터페이스 제약 조건이 있는 경우에만 유효합니다. S가 M이 선언된 유형인 컬렉션의 각 멤버 S.M에 대해 S가 객체가 아닌 클래스 선언인 경우 다음 규칙이 적용됩니다
- M이 상수, 필드, 속성인 경우 , 이벤트, 열거형 멤버 또는 유형 선언이 있는 경우 인터페이스 선언에 선언된 모든 멤버가 이 세트에서 제거됩니다.
- M이 메소드인 경우 인터페이스 유형에 선언된 메소드가 아닌 모든 멤버는 이 세트에서 제거되고 S와 인터페이스에 선언된 M의 서명이 동일한 모든 메소드는 이 세트에서 제거됩니다. . 이 컬렉션에서 제거되었습니다.
마지막으로 숨겨진 멤버를 삭제한 후 검색 결과가 결정됩니다
- 컬렉션이 유형이나 메소드가 아닌 단일 멤버로 구성된 경우 이 멤버가 결과입니다. 검색의.
- 그렇지 않고 세트에 메소드만 포함된 경우 이 메소드 세트가 검색 결과입니다.
- 그렇지 않고 세트에 유형 선언만 포함된 경우 이 유형 선언 세트는 멤버 조회 결과에 있습니다.
- 그렇지 않으면 조회가 모호해지고 컴파일 타임 오류가 발생합니다.
유형의 경우 유형 매개변수 및 인터페이스의 멤버 조회가 아닌 인터페이스의 멤버 조회는 엄격히 단일 상속입니다(상속 체인의 각 인터페이스에는 정확히 0개 또는 1개의 직접 기본 인터페이스가 있음), 조회 규칙의 효과는 다음과 같습니다. 파생 멤버는 동일한 이름과 서명을 가진 기본 클래스 멤버를 숨깁니다. 이 단일 상속 조회는 매우 명시적입니다. 멤버 조회에서 발생할 수 있는 모호성은 §13.2.5
20.9.3 단순 이름
에 설명된 다중 상속 인터페이스에서 발생합니다.다음 내용은 §7.5.2를 대체할 수 있습니다.
간단한 이름은 식별자와 그 뒤에 오는 선택적 유형 매개변수 목록으로 구성됩니다.
단순 이름: (단순 이름:)
식별자 유형-인수 목록 opt (식별자 유형 인수 목록 선택 사항)
I 또는 If53db7e3537772cbf9ba1634d2b17fe6 형식의 단순 이름의 경우; 여기서 I는 식별자이고 I
단순 이름이 블록 내에 나타나고, 블록의 지역 변수 선언 공간에 I가 지정한 이름의 지역 변수나 매개 변수가 포함되어 있는 경우 단순 이름은 지역 변수와 매개 변수를 참조하며 다음과 같은 역할을 합니다. 변수 그리고 분류됩니다. 형식 인수 목록을 지정하면 컴파일 타임 오류가 발생합니다.
일반 메소드 선언의 본문 내에 단순 이름이 나타나고 해당 선언에 I라는 유형 매개변수가 포함되어 있는 경우 단순 이름은 유형 인수 목록만 지정된 경우 해당 유형 매개변수를 참조합니다. 컴파일 타임 오류가 발생했습니다.
그렇지 않은 경우, 직접 바깥쪽 클래스, 구조체 또는 열거형에서 선언한 인스턴스 유형으로 시작하는 T 유형의 각 인스턴스에 대해 바깥쪽 각 외부 클래스 또는 구조체(있는 경우)에서 선언한 인스턴스 유형을 계속 사용합니다.
- T 선언에 I라는 유형 매개변수가 포함된 경우 단순 이름은 해당 유형 매개변수를 참조합니다. 형식 인수 목록을 지정하면 컴파일 타임 오류가 발생합니다.
- 그렇지 않고 T에서 I의 멤버 조회가 일치를 생성하는 경우
u T가 직접 포함하는 클래스 또는 구조체 유형의 인스턴스 유형이고 조회가 하나 이상의 메소드를 식별하는 경우 결과는 다음과 같습니다. 이 표현식과 연관된 메소드 그룹과 일치합니다. 형식 인수 목록이 지정된 경우 일반 메서드 호출(§20.6.3)에 사용됩니다.
u T가 직접 포함하는 클래스 또는 구조체 유형의 인스턴스 유형인 경우 조회에서 인스턴스 멤버를 식별하고 참조가 인스턴스 생성자, 인스턴스 메서드 또는 인스턴스 접근자의 블록 내에서 발생하면 결과는 다음과 같습니다. .I 형식의 회원 액세스도 비슷합니다. 형식 인수를 지정하면 컴파일 타임 오류가 발생합니다.
u 그렇지 않으면 결과는 T.I 또는 T.If53db7e3537772cbf9ba1634d2b17fe6 형식의 회원 액세스와 유사합니다. 이 경우 간단한 이름으로 인스턴스 멤버를 참조하는 것은 컴파일 타임 오류입니다.
그렇지 않으면 단순 이름이 나타나는 각 네임스페이스가 있는 네임스페이스 N에 대해 각 둘러싸는 네임스페이스(있는 경우)로 계속되고 전역 네임스페이스로 끝납니다. 다음 단계는 엔터티가 나타날 때까지 계산됩니다. 위치하고 있습니다.
- I가 N의 네임스페이스 이름이고 형식 인수 목록이 지정되지 않은 경우 단순 이름은 해당 네임스페이스를 참조합니다.
- 그렇지 않고 I가 일치하는 수의 유형 인수를 가진 N에서 액세스 가능한 유형의 이름인 경우 단순 유형은 주어진 유형 인수로 구성된 해당 유형을 참조합니다.
u 네임스페이스 선언에 I가 지정한 이름과 연결된 using alias 지시문이 포함되어 있고(여기서 I는 가져온 네임스페이스 또는 유형이고 유형 인수 목록이 지정되지 않은 경우) 단순 이름은 네임스페이스 또는 유형을 참조합니다.
u 그렇지 않고 네임스페이스 선언의 using 네임스페이스 지시문에 의해 가져온 네임스페이스에 형식 인수 수와 일치하는 I라는 이름의 형식이 포함되어 있으면 지정된 형식 인수 형식에서 간단한 이름 참조가 생성됩니다.
u 그렇지 않고 네임스페이스 선언의 using 네임스페이스 지시문으로 가져온 네임스페이스에 I에서 지정한 이름이 형식 인수 수와 일치하는 여러 형식이 포함되어 있으면 단순 이름이 모호해지고 컴파일 시간 오류가 발생합니다.
l 그렇지 않으면 단순 이름으로 지정된 이름이 정의되지 않고 컴파일 시간 오류가 발생합니다.
20.9.4 회원 접속
다음 내용은 §7.5.4를 대체할 수 있습니다.
멤버 액세스는 기본 표현식 또는 미리 정의된 유형, "." 표시, 식별자, 선택적 유형 인수 목록으로 구성됩니다.
member-access: (멤버 액세스:)
기본 표현식 .식별자 유형-인수 목록 opt(기본 표현식. 식별자 유형 인수 목록 선택 사항)
미리 정의된 유형-인수- list opt (사전 정의된 유형. 식별자 유형 인수 목록 선택 사항) 사전 정의된 유형: 다음 중 하나
bool byte chardecimal double float int long
object sbyte short string uint ulong ushort
멤버용 E.I 또는 E.If53db7e3537772cbf9ba1634d2b17fe6 형식의 액세스(여기서 E는 기본 표현식 또는 미리 정의된 유형이고 I는 식별자이며 f53db7e3537772cbf9ba1634d2b17fe6는 선택 사항임) 다음과 같이 계산되어 정렬됩니다.
E가 네임스페이스이고 I가 E에 중첩된 네임스페이스의 이름이고 형식 인수가 지정되지 않은 경우 결과는 이 네임스페이스입니다.
E가 네임스페이스이고 I가 E에서 액세스할 수 있는 유형의 이름이고 E가 유형 매개변수의 수와 일치하는 경우 결과는 지정된 유형 인수로 구성된 유형입니다.
E가 미리 정의된 유형이거나 유형으로 분류된 기본 표현식이고 E가 유형 매개변수가 아닌 경우 E에서 I의 멤버 조회가 일치하는 경우 E.I는 다음과 같이 평가되고 분류됩니다.
- 하나 이상의 유형 선언을 식별하는 경우 해당 유형 선언은 유형 인수에 제공된 것과 동일한 수(0개일 수도 있음)의 유형 인수를 사용하여 결정됩니다. 결과는 주어진 유형 인수로 구성된 유형입니다. 유형 선언이 유형 매개변수 수와 일치하지 않으면 컴파일 타임 오류가 발생합니다.
- 하나 이상의 메서드를 식별하면 결과는 연결된 인스턴스 표현식이 없는 메서드 그룹입니다. 형식 인수 목록이 지정되면 일반 메서드 호출에 사용됩니다(§20.6.3).
- 정적 속성, 정적 필드, 정적 이벤트, 상수 또는 열거형 멤버를 식별하는 경우 형식 인수 목록이 지정되면 컴파일 타임 오류가 발생합니다.
- 정적 속성을 식별하면 연결되지 않은 인스턴스 표현식을 사용하여 속성에 액세스하게 됩니다.
- 정적 필드를 식별하는 경우
u 필드가 읽기 전용이고 참조가 클래스 또는 구조체의 정적 생성자 외부에서 발생하는 경우 필드가 여기에서 선언됩니다. 그러면 결과는 E의 정적 필드 I의 값인 값입니다.
u 그렇지 않으면 결과는 E의 정적 필드 I인 변수입니다.
- 정적 이벤트를 식별하는 경우
u 이벤트가 선언된 클래스 또는 구조에서 참조가 발생하고 이벤트 접근자 선언(§10.7) 없이 이벤트가 선언된 경우 E.I는 마치 내가 정적 장인 것처럼 취급되었습니다.
u 그렇지 않은 경우 결과는 연결되지 않은 인스턴스 표현식에 대한 이벤트 액세스입니다.
- 상수를 식별하면 결과는 상수의 값인 값입니다.
- 열거형 멤버를 식별하면 결과는 열거형 멤버의 값입니다.
- 그렇지 않으면 E.I는 잘못된 멤버 참조이며 컴파일 타임 오류가 발생합니다.
E가 유형이 T인 속성 액세스, 인덱서 액세스, 변수 또는 값이고 T에서 I의 멤버 조회가 일치 항목을 생성하는 경우 E.I는 다음과 같이 계산되고 분류됩니다.
- 먼저 E가 속성 또는 인덱서 액세스인 경우 속성 또는 인덱서 액세스의 값을 얻고(§7.1.1) E를 값으로 재분류합니다.
- 하나 이상의 메소드를 식별하면 결과는 E라는 연관된 인스턴스 표현식이 있는 메소드 그룹입니다. 형식 인수 목록이 지정되면 일반 메서드 호출에 사용됩니다(§20.6.3).
- 인스턴스 속성, 인스턴스 필드 또는 인스턴스 이벤트를 식별하는 경우 형식 인수 목록이 지정되면 컴파일 타임 오류가 생성됩니다.
- 인스턴스 속성을 식별하면 결과는 연결된 E 가 있는 인스턴스 표현식입니다.
- T가 클래스 유형이고 I가 클래스 유형의 인스턴스 필드를 식별하는 경우
u E의 값이 null이면 System.NullReferenceException이 발생합니다.
u 그렇지 않고 필드가 읽기 전용이고 필드가 선언된 클래스의 인스턴스 생성자 외부에서 참조가 발생하는 경우 결과는 E가 참조하는 객체의 I 값입니다.
u 그렇지 않은 경우 결과는 E가 참조하는 개체의 I 필드인 변수입니다.
- T가 구조체 유형이고 I가 해당 구조체 유형의 인스턴스 필드를 식별하는 경우
u E가 값이거나 필드가 읽기 전용이고 참조가 구조체의 인스턴스 생성자에 나타나는 경우 필드가 달리 선언된 경우 결과는 값, 즉 E가 제공한 구조 인스턴스의 필드 I 값입니다.
u 그렇지 않은 경우 결과는 변수입니다. 즉, E에서 제공한 구조의 인스턴스에 있는 필드 I입니다.
- 인스턴스 이벤트를 식별하는 경우
u 참조가 클래스 또는 구조에 나타나는 경우; 이벤트가 내부에 선언되었고 이벤트 접근자 선언 없이 이벤트가 선언된 경우 E.I는 마치 인스턴스 필드인 것처럼 처리됩니다.
u 그렇지 않으면 결과는 연관된 E가 있는 인스턴스 표현식입니다.
그렇지 않으면 E.I는 잘못된 멤버 참조이며 컴파일 타임 오류가 발생합니다.
20.9.5 메소드 호출
§7.5.5.1의 메소드 호출을 기술하는 컴파일 타임 처리 부분을 다음 내용으로 대체할 수 있습니다.
M(A) 형식의 메서드 호출을 컴파일 타임에 처리합니다. 여기서 M은 메서드 그룹(형식 인수 목록을 포함할 수 있음)이고 A는 선택적 인수 목록이며 다음 단계로 구성됩니다.
메서드 호출의 후보 집합이 구성됩니다. 메서드 그룹 M과 연결된 각 메서드 F
에 대해 - F가 제네릭이 아닌 경우
u M에 형식 인수 목록이 없고 A의 경우
u인 경우 F가 후보입니다(§7.4. 2.1), F가 적용됩니다.
- F가 제네릭이고 M에 형식 인수 목록이 없는 경우 F는 후보입니다.
u 유추된 형식 인수가 해당 메서드 형식 매개 변수를 대체하면 F의 매개 변수 목록이 A에 적용 가능합니다. 및
u 유형 인수가 교체된 후 F의 매개변수 목록은 최대한 적용 가능합니다. 동일한 유형에서 F로 선언된 제네릭이 아닌 메서드는 확장 형식이 다릅니다(§7.4.2.1).
- F가 제네릭이고 M에 형식 인수 목록이 포함된 경우 F는 매개변수일 때 후보이고
u 형식 인수가 해당 메서드 형식 매개변수를 대체하면 F의 매개변수 목록이 A에 적용 가능합니다( §7.4.2.1).
후보 메서드 집합은 깊이 파생된 형식에서 파생된 메서드만 포함하도록 축소되었습니다. 집합의 모든 C.F 메서드에 대해 C는 F가 선언된 형식이고 C의 기본 형식은 다음에서 선언됩니다. 의 모든 메서드가 컬렉션에서 제거됩니다.
후보 메소드의 결과 세트가 비어 있으면 적용 가능한 메소드가 존재하지 않으며 컴파일 타임 오류가 발생합니다. 후보 메소드가 동일한 유형으로 선언되지 않으면 메소드 호출이 모호해지고 컴파일 시간 오류가 발생합니다(이 후자의 경우는 여러 직접 기본 인터페이스가 있는 인터페이스의 메소드에만 가능함). §13.2.5).
오버로드 결정 규칙(§7.4.2)을 사용하여 후보 메서드 집합 중 가장 좋은 메서드를 식별합니다. 가장 좋은 단일 메서드를 식별할 수 없으면 메서드 호출이 모호해지고 컴파일 시간 오류가 발생합니다. 오버로드 해결을 수행할 때 해당 메서드 형식 매개 변수를 형식 인수(제공 또는 유추)로 바꾼 후 제네릭 메서드의 매개 변수가 고려됩니다.
- 메소드는 메소드 그룹의 컨텍스트에서 유효합니다. 메소드가 정적 메소드인 경우 메소드 그룹은 단순 이름 또는 회원 액세스. 가장 좋은 메서드가 인스턴스 메서드인 경우 메서드 그룹은 변수나 값 또는 단순 이름이나 멤버 액세스에서 파생된 기본 액세스를 통해 액세스할 수 있어야 합니다. 이러한 요구 사항 중 어느 것도 충족되지 않으면 컴파일 타임 오류가 발생합니다.
- 최상의 메서드가 제네릭 메서드인 경우 제네릭 메서드에 선언된 제약 조건에 대해 형식 인수(제공 또는 유추)가 확인됩니다. 형식 인수가 해당 형식 매개 변수의 제약 조건을 충족하지 않으면 컴파일 시간 오류가 생성됩니다.
이전 단계에 따라 메서드가 선택되고 확인되면 실제 런타임 호출은 §7.4의 함수 멤버 호출 규칙에 따라 처리됩니다.
20.9.6 위임 생성 표현
다음 내용은 §7.5.10.3의 대리자 생성 표현식의 컴파일 시간 처리 부분을 대체할 수 있습니다.
new D(E) 형식의 대리자 생성 식(여기서 D는 대리자 유형이고 E는 식)의 컴파일 타임 처리는 다음 단계로 구성됩니다.
E가 메소드 그룹인 경우
- E(A) 형식의 메소드 호출에 해당하면 단일 메소드 호출이 선택됩니다.
u D의 매개변수 유형 및 수정자(ref 또는 out)는 인수 목록 A의 인수 유형 및 수정자로 사용됩니다.
u 해당 테스트 및 유형 추론에서는 변환이 고려되지 않습니다. 암시적 변환만으로 충분한 경우 유형 요구 사항은 동일합니다.
u 과부하 결정 단계는 실행되지 않습니다. 대신 후보 집합에는 정확히 하나의 D 호환 메서드(유형 매개 변수 대신 형식 인수 사용)가 포함되어야 하며 이 메서드는 새로 생성된 대리자가 참조하는 메서드가 됩니다. 일치하는 메서드가 없거나 여러 개의 일치하는 메서드가 있는 경우 컴파일 타임 오류가 발생합니다.
- 선택한 메서드가 인스턴스 메서드인 경우 E와 연결된 인스턴스 표현식이 대리자의 대상 개체를 결정합니다.
- 결과는 선택한 메서드와 대상 개체의 새로 생성된 대리자를 참조하는 D 유형의 값입니다.
그렇지 않으면 E는 대리자 유형의 값입니다.
- D와 E는 호환되어야 합니다. 그렇지 않으면 컴파일 시간 오류가 발생합니다.
- 결과는 D 유형의 값입니다. 즉, E와 동일한 통화 목록을 참조하는 새로 생성된 대리자입니다.
그렇지 않으면 위임 생성 표현식이 유효하지 않으며 컴파일 타임 오류가 발생합니다.
20.10 오른쪽 시프트 구문 변경
제네릭은 "fbd1e5096808aa74fa5b6ea80f0e9fae" 문자를 사용하여 유형 매개변수와 유형 인수를 구분합니다(C++의 템플릿 구문과 유사). Listdd77601bbe5f7db04992ba7b2f8dd60c>와 같이 생성된 유형은 때때로 중첩될 수 있지만 이 구문을 사용하는 데는 몇 가지 미묘한 구문 문제가 있습니다. 어휘 분석기는 이 구문의 마지막 두 토큰인 ">>"를 결합합니다. 시프트 연산자) 구문에 필요한 두 개의 ">" 태그를 생성하는 대신. 가능한 해결책 중 하나는 두 개의 ">>" 사이에 공백을 두는 것이지만, 이 역시 어색하고 혼란스러우며 어떤 방식으로든 프로그램의 단순성을 증가시키지 않습니다.
이러한 중립 구문의 어휘 단순성을 유지하기 위해 ">>" 및 ">>=" 표시가 어휘집에서 제거되고 오른쪽 시프트 및 오른쪽 시프트 할당 생성으로 대체되었습니다.
연산자 또는 구두점:
{ } [ ] ( ) . : ;
+ - * / % & | ^ ! ~
= f05b8af2c175d5709927ed8b6c4f873e
!= b207bb093495751f3e536c5eb7122819= += -= *= /= %= &= |=
^= 2ed8ed9bdd005f2bb2838bea551bc980 >
오른쪽 시프트 할당: (오른쪽 시프트 할당)
> >=
구문의 다른 생성과 달리 문자가 없습니다. 오른쪽 시프트와 오른쪽 시프트 할당 생성의 토큰 사이에는 종류(공백 포함)가 허용됩니다.
다음 제작은 오른쪽 시프트 또는 오른쪽 시프트 할당을 사용하여 수정됩니다.
shift-expression: (shift 표현식:)
additive-expression (추가 표현식)
shift-expression ddd0620b42f67e0c3fae74991e3d1d10=
<=
(일반 끝)
******* ***********************
위 내용은 C# 2.0 스펙(Generic 6) 내용이므로 주의하시기 바랍니다. 더 많은 관련 콘텐츠를 보려면 PHP 중국어 웹사이트(www.php.cn)를 방문하세요!