"소수"가 유효한 속성 매개 변수 유형이 아닌 이유는 무엇입니까?


139

정말 믿을 수 없지만 진짜입니다. 이 코드는 작동하지 않습니다 :

[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
public class Range : Attribute
{
    public decimal Max { get; set; }
    public decimal Min { get; set; }
}

public class Item
{
    [Range(Min=0m,Max=1000m)]  //compile error:'Min' is not a valid named attribute argument because it is not a valid attribute parameter type 
    public decimal Total { get; set; }  
}

이것이 작동하는 동안 :

[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
public class Range : Attribute
{
    public double Max { get; set; }
    public double Min { get; set; }
}

public class Item
{
    [Range(Min=0d,Max=1000d)]
    public decimal Total { get; set; }  
}

십진수가 아닌 동안 왜 double이 OK인지 누가 알 수 있습니까?


답변:


139

이것은 CLR 제한입니다. 기본 상수 또는 기본 배열 만 속성 매개 변수로 사용할 수 있습니다. 그 이유는 속성이 메타 데이터로 완전히 인코딩되어야하기 때문입니다. 이것은 IL로 코딩 된 메소드 본문과 다릅니다. MetaData를 사용하면 사용할 수있는 값의 범위 만 심각하게 제한합니다. CLR의 현재 버전에서 메타 데이터 값은 프리미티브, 널 (null), 유형 및 프리미티브 배열로 제한됩니다 (사소한 것이 누락되었을 수 있음).

답변 에서 가져온 JaredPar .

기본 유형 인 소수는 기본 유형이 아니므로 메타 데이터로 표현할 수 없으므로 속성 매개 변수가되지 않습니다.


35
CLR에서 소수가 기본 유형으로 간주되지 않는 이유는 무엇입니까?
koumides

10
@koumides 내가 대답이 유형은 128 비트이기 때문에 하나의 CPU 레지스터에 표현하기 위해 너무 큰 믿는다
크리스 Marisic

2
그렇다면 왜 문자열이 속성 속성으로 허용됩니까? 나는 그것이 '기본 배열'범주에 속한다고 가정하지만 그것은 힙 할당 (참조 유형)입니다.
Steztric

문자열은 완전히 다른 방식으로 처리되는 참조 유형이기 때문입니다.
Carsten Schütte

2
@Soren 이것은 사실이 아니며 Enum지원됩니다. 나는 현재 2 개의 열거 형을 가진 2 개의 사용자 정의 속성과 enum 배열을 가진 2 개의 사용자 정의 속성을 가지고 있습니다.
Franck

60

로부터 사양 :

속성 클래스의 위치 및 명명 된 매개 변수 유형은 다음과 같은 속성 매개 변수 유형으로 제한됩니다.

  • 다음 유형 중 하나 : bool, byte, char, double, float, int, long, sbyte, short, string, uint, ulong, ushort.
  • 유형 object입니다.
  • 유형 System.Type입니다.
  • 열거 형은 공개 접근성 및 중첩 된 유형 (있는 경우)도 공개 접근성 (속성 사양)을 갖습니다.
  • 위 유형의 1 차원 배열.

10
정확하지만 이전 버전의 사양을 인용하고 있습니다. C #을 버전 3.0, 4.0, 5.0에서, 그것은 그것은 또한 유형을 가질 수 있음을 언급한다 sbyte, ushort, uint, ulong. 그리고 그것은 잘 작동하는 것 같습니다. 그러나 여전히 decimal허용되지 않습니다 :-(
Jeppe Stig Nielsen

1
나는 사양 링크 및 견적 업데이트되었습니다 @JeppeStigNielsen
오핫 슈나이더

6
널 입력 가능 기본 요소도 지원되지 않습니다.
KTCO

2

이 문제에 대한 답은 원자 유형이 아니더라도 속성으로 허용되는 문자열을 사용하는 것입니다. 반올림으로 인해 결과의 정확도가 떨어 지므로 복식을 사용하지 마십시오.

public String MinimumValue
{
    get
    {
        return minimumValueDecimal.ToString();
    }

    set
    {
        minimumValueDecimal = Decimal.Parse(value);
    }
}

private decimal minimumValueDecimal;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.