문제

이렇게 컴파일 시간은 예외:

public sealed class ValidatesAttribute<T> : Attribute
{

}

[Validates<string>]
public static class StringValidation
{

}

나는 깨닫 C#지원하지 않는 일반적인 속성이 있습니다.그러나,이후 많은 인터넷 검색,나를 찾을 수 없습니다.

사람이 왜 알고 있는 일반 형식이 없습에서 파생 Attribute?모든 이론?

도움이 되었습니까?

해결책

글쎄, 나는 그것이 왜 그것을 사용할 수 없는지 대답 할 수 없지만 나는 ~할 수 있다 CLI 문제가 아님을 확인하십시오. CLI 사양은 (내가 볼 수있는 한) 언급하지 않으며 IL을 직접 사용하면 일반 속성을 만들 수 있습니다. 10.1.4 절을 금지하는 C# 3 사양의 일부는 "클래스 기본 사양"섹션은 정당화를 제공하지 않습니다.

주석이 달린 ECMA C# 2 사양은 유용한 정보를 제공하지 않지만 허용되지 않은 내용의 예를 제공합니다.

주석이 달린 C# 3 사양 사본이 내일 도착해야합니다 ... 더 많은 정보가 제공되는지 확인하겠습니다. 어쨌든, 그것은 런타임이 아닌 언어 결정입니다.

편집 : Eric Lippert (Paraphrased)의 답변 : 많은 가치를 더하지 않는 사용 사례에 대한 언어와 컴파일러의 복잡성을 피하는 것 외에는 특별한 이유가 없습니다.

다른 팁

속성은 컴파일 타임에 클래스를 장식하지만 일반 클래스는 런타임까지 최종 유형 정보를 수신하지 않습니다. 속성이 컴파일에 영향을 줄 수 있으므로 컴파일 시간에 "완료"해야합니다.

이것 좀 봐 MSDN 기사 자세한 내용은.

왜 허용되지 않는지 모르겠지만 이것은 가능한 해결 방법 중 하나입니다.

[AttributeUsage(AttributeTargets.Class)]
public class ClassDescriptionAttribute : Attribute
{
    public ClassDescriptionAttribute(Type KeyDataType)
    {
        _KeyDataType = KeyDataType;
    }

    public Type KeyDataType
    {
        get { return _KeyDataType; }
    }
    private Type _KeyDataType;
}


[ClassDescriptionAttribute(typeof(string))]
class Program
{
    ....
}

이것은 진정으로 일반적이지 않으며 유형 당 특정 속성 클래스를 작성해야하지만 일반적인 기본 인터페이스를 사용하여 약간 방어 적으로 코딩하고 다른 방법보다 적은 코드를 작성하고 다형성의 이점을 얻을 수 있습니다.

//an interface which means it can't have its own implementation. 
//You might need to use extension methods on this interface for that.
public interface ValidatesAttribute<T>
{
    T Value { get; } //or whatever that is
    bool IsValid { get; } //etc
}

public class ValidatesStringAttribute : Attribute, ValidatesAttribute<string>
{
    //...
}
public class ValidatesIntAttribute : Attribute, ValidatesAttribute<int>
{
    //...
}

[ValidatesString]
public static class StringValidation
{

}
[ValidatesInt]
public static class IntValidation
{

}

이것은 아주 좋은 질문입니다. 속성에 대한 나의 경험에서, 나는 속성을 반영 할 때 가능한 모든 유형의 순열을 확인 해야하는 조건을 생성하기 때문에 제약 조건이 마련되어 있다고 생각합니다. typeof(Validates<string>), typeof(Validates<SomeCustomType>), 등...

제 생각에는 유형에 따라 사용자 정의 검증이 필요한 경우 속성이 최선의 접근 방식이 아닐 수 있습니다.

아마도 a SomeCustomValidationDelegate 또는 ISomeCustomValidator 매개 변수가 더 나은 접근 방식이 될 것입니다.

내 해결 방법은 다음과 같습니다.

public class DistinctType1IdValidation : ValidationAttribute
{
    private readonly DistinctValidator<Type1> validator;

    public DistinctIdValidation()
    {
        validator = new DistinctValidator<Type1>(x=>x.Id);
    }

    public override bool IsValid(object value)
    {
        return validator.IsValid(value);
    }
}

public class DistinctType2NameValidation : ValidationAttribute
{
    private readonly DistinctValidator<Type2> validator;

    public DistinctType2NameValidation()
    {
        validator = new DistinctValidator<Type2>(x=>x.Name);
    }

    public override bool IsValid(object value)
    {
        return validator.IsValid(value);
    }
}

...
[DataMember, DistinctType1IdValidation ]
public Type1[] Items { get; set; }

[DataMember, DistinctType2NameValidation ]
public Type2[] Items { get; set; }

이것은 현재 C#언어 기능,그러나이 많은 논의가 있는 공식 C#언어 repo.

일부 회 노트:

심지어는 것이 비록 작업 원칙적으로,거기에는 버그에서 가장 런타임 버전은 그렇게는 그것이 제대로 작동하지 않을 것(그 행사 적).

우리가 필요한 메커니즘을 이해하는 대상 런타임에서 작동.리 필요에 대한 많은 것들이,그리고 현재 보고 있습니다.지 그런 다음 우리는 걸릴 수 없습니다.

후보에 대한 주요 C#버전 경우,우리가 만들 수 있습니다 충분한 숫자 의 런타임 버전 처리합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top