developer tip

"스페셜 클래스"란 정확히 무엇입니까?

optionbox 2020. 7. 25. 10:49
반응형

"스페셜 클래스"란 정확히 무엇입니까?


컴파일하기 위해 다음과 같은 것을 얻지 못한 후 :

public class Gen<T> where T : System.Array
{
}

오류와 함께

제약 조건은 특수 클래스`System.Array '일 수 없습니다

"스페셜 클래스" 정확히 무엇인지 궁금해하기 시작했습니다 .

사람들 System.Enum은 일반적인 제약 조건으로 지정할 때 종종 같은 종류의 오류가 발생하는 것처럼 보입니다 . 나는과 같은 결과를 얻었다 System.Object, System.Delegate, System.MulticastDelegateSystem.ValueType도합니다.

더 있나요? C #에서 "특수 클래스"에 대한 정보를 찾을 수 없습니다.

또한, 무엇 이며 우리가 제네릭 형식 제약 조건으로 사용할 수없는 그 클래스에 대한 특별?


Roslyn 소스 코드에서 하드 코드 된 유형의 목록처럼 보입니다.

switch (type.SpecialType)
{
    case SpecialType.System_Object:
    case SpecialType.System_ValueType:
    case SpecialType.System_Enum:
    case SpecialType.System_Delegate:
    case SpecialType.System_MulticastDelegate:
    case SpecialType.System_Array:
        // "Constraint cannot be special class '{0}'"
        Error(diagnostics, ErrorCode.ERR_SpecialTypeAsBound, syntax, type);
        return false;
}

출처 : Binder_Constraints.cs IsValidConstraintType
GitHub 검색을 사용하여 찾았습니다 : "제약은 특수 클래스가 될 수 없습니다"


비슷한 질문에 대해 2008 년부터 Jon Skeet 의견을 찾았습니다 . System.Enum제약 조건 지원 되지 않는 이유는 무엇입니까?

나는 이것이 약간의 주제라는 것을 알고 있지만 Eric Lippert (C # 팀)에게 그것에 대해 물었고 그들은 다음과 같은 대답을 제공했습니다.

먼저, 추측은 맞습니다. 제약 조건에 대한 제한은 CLR이 아니라 언어의 인공물입니다. (이러한 기능을 수행하려면 열거 가능한 유형을 지정하는 방법과 관련하여 CLR에서 변경하고 싶은 몇 가지 사소한 것이 있지만 대부분 언어로 작동합니다.)

둘째, 나는 컴파일러가 당신을 당신으로부터 구하기 위해 위임 제약 조건, 열거 제약 조건 및 오늘날 불법적 인 제약 조건을 지정할 수있는 기능을 개인적으로 원합니다. 즉, 봉인 된 유형을 제약 조건으로 합법화하는 등입니다.

그러나 예약 제한으로 인해 이러한 기능을 다음 언어 버전으로 가져올 수 없을 것입니다.


MSDN 에 따르면 정적 클래스 목록입니다.

컴파일러 오류 CS0702

제약 조건은 특수 클래스 '식별자'일 수 없습니다. 다음 유형은 제약 조건으로 사용할 수 없습니다.

  • System.Object
  • System.Array
  • System.Delegate
  • System.Enum
  • System.ValueType.

C # 4.0 언어 사양 (코드 : [10.1.5] 형식 매개 변수 제약 조건)에 따라 두 가지 사항이 있습니다.

1] The type must not be object. Because all types derive from object, such a constraint would have no effect if it were permitted.

2] If T has no primary constraints or type parameter constraints, its effective base class is object.

When you define a generic class, you can apply restrictions to the kinds of types that client code can use for type arguments when it instantiates your class. If client code tries to instantiate your class by using a type that is not allowed by a constraint, the result is a compile-time error. These restrictions are called constraints. Constraints are specified by using the where contextual keyword. If you want to constrain a generic type to be a reference type, use : class.

public class Gen<T> where T : class
{
}

This will prohibit the generic type from being a value type, such as int or a struct etc.

Also, Constraint cannot be special class 'identifier' The following types may not be used as constraints:

  • System.Object
  • System.Array
  • System.Delegate
  • System.Enum
  • System.ValueType.

There are certain classes in the Framework which effectively pass on special characteristics to all types derived from them but do not possess those characteristics themselves. The CLR itself imposes no prohibition against using those classes as constraints, but generic types constrained to them would not acquire the non-inherited characteristics the way concrete types would. The creators of C# decided that because such behavior might confuse some people, and they failed to see any usefulness to it, they should prohibit such constraints rather than allow them to behave as they do in the CLR.

If, for example, one were allowed to write: void CopyArray<T>(T dest, T source, int start, int count); one would be able to pass dest and source to methods which expect an argument of type System.Array; further, one would get compile-time validation that dest and source were the compatible array types, but one would not be able to access elements of the array using the [] operator.

The inability to use Array as a constraint is mostly pretty easy to work around, since void CopyArray<T>(T[] dest, T[] source, int start, int count) will work in almost all situation where the former method would work. It does, however, have a weakness: the former method would work in the scenario that one or both of the arguments was of type System.Array while rejecting cases where the arguments are incompatible array types; adding an overload where both arguments were of type System.Array would make the code accept the additional cases it should accept, but also make it erroneously accept cases it should not.

I find the decision to outlaw most of the special constraints irksome. The only one which would have zero semantic meaning would be System.Object [since if that were legal as a constraint, anything would satisfy it]. System.ValueType probably wouldn't be very useful, since references of type ValueType don't really have much in common with value types, but it might plausibly have some value in cases involving Reflection. Both System.Enum and System.Delegate would have some real uses, but since the creators of C# didn't think of them they're outlawed for no good reason.


The following can be found in CLR via C# 4th Edition:

Primary Constraints

A type parameter can specify zero primary constraints or one primary constraint. A primary constraint can be a reference type that identifies a class that is not sealed. You cannot specify one of the following special reference types: System.Object, System.Array, System.Delegate, System.MulticastDelegate, System.ValueType, System.Enum, or System.Void. When specifying a reference type constraint, you are promising the compiler that a specified type argument will either be of the same type or of a type derived from the constraint type.


I don't think, that there exists any official definition of "special classes"/"special types".

You may think about them a a types, which can't be used with semantic of "regular" types:

  • you can't instantiate them directly;
  • you can't inherit custom type from them directly;
  • there is some compiler magic to work with them (optionally);
  • the direct usage of their instances at least useless (optionally; imagine, that you've created generic above, what generic code are you going to write?)

P.S. I'd add System.Void to the list.

참고URL : https://stackoverflow.com/questions/29961823/what-exactly-is-a-special-class

반응형