C#의 특정 유형에만 적용될 수 있도록 사용자 정의 속성을 제한 하시겠습니까?
-
06-07-2019 - |
문제
클래스 속성과 클래스 자체에 적용되는 사용자 정의 속성이 있습니다. 이제 내 사용자 정의 속성을 적용 해야하는 모든 클래스는 단일 기본 클래스에서 파생됩니다.
내 사용자 지정 속성을 어떻게 내 기본 클래스에서 파생 해야하는 클래스에만 적용 할 수 있도록 어떻게 할 수 있습니까? 어떻게해야합니까?
해결책
DARN, 내가 틀린 것을 증명할 때 나는 그것을 싫어한다 ... 속성을 보호 기본 등급의 중첩 유형 :
abstract class MyBase {
[AttributeUsage(AttributeTargets.Property)]
protected sealed class SpecialAttribute : Attribute {}
}
class ShouldBeValid : MyBase {
[Special]
public int Foo { get; set; }
}
class ShouldBeInvalid {
[Special] // type or namespace not found
[MyBase.Special] // inaccessible due to protection level
public int Bar{ get; set; }
}
(원본 답변)
적어도 컴파일 시간이 아니라 이것을 할 수 없습니다.
속성은 "클래스", "구조", "메소드", "필드"등으로 제한 될 수 있지만 더 세분화 된 것은 없습니다.
물론, 속성은 그 자체로는 아무것도하지 않기 때문에 (사후 사후 무시) 다른 유형에서는 불활성이 될 것입니다 (런타임에 속성을 보려면 코드를 추가하지 않는 한 유형에 불활성이 있습니다).
FXCOP 규칙을 작성할 수는 있지만 과도하게 보입니다.
그러나 속성이 최선의 선택인지 궁금합니다.
이제 내 사용자 정의 속성을 적용 해야하는 모든 클래스는 단일 기본 클래스에서 파생됩니다.
만약 그들이 ~ 해야 하다 사용자 정의 속성을 적용하십시오 abstract
(또는 아마도 virtual
) 속성 / 방법이 더 나은 선택일까요?
abstract class MyBase {
protected abstract string GetSomeMagicValue {get;}
}
class MyActualType : MyBase {
protected override string GetSomeMagicValue {get {return "Foo";}}
}
다른 팁
나는 사용자 지정 속성으로 이것을 할 수있는 방법을 모른다.
더 좋은 방법은 클래스가 일반적인 제약 조건으로 인터페이스를 구현하도록하는 것입니다.
그래서
class MyAttribute
{
// put whatever custom data you want in here
}
interface IAttributeService<T> where T : MyBaseClass
{
MyAttribute Value{get;}
}
그러면 기본 클래스가 이것을 할 것입니다
class MyBaseClass : IAttributeService<MyBaseClass>
{
private MyAttribute m_attrib;
IAttributeService<MyClass>.Value
{
get {return m_attrib;}
}
}
그렇게하면 컴파일러가 컴파일 타임에 제약 조건을 시행하여 클래스 만
MyBaseClass에서 파생 된 인터페이스를 구현할 수 있습니다.
MyAttribute 클래스를 정의하여 상당히 확장 가능했지만 물론 더 간단한 것이 필요하면 문자열이나 bool을 반환 할 수 있습니다.
또한 MyAttribute 회원을 비공개로 만들었으므로 파생 클래스가 그것을보고 변경할 수는 없지만 원하는 경우 파생 클래스 액세스를 허용 할 수 있습니다.