2009-06-20 8 views
11

Sınıf özelliklerine ve sınıfın kendisine uygulanan bir özel özniteliğim var. Şimdi, özel özniteliğimi uygulamak zorunda olan tüm sınıflar, tek bir temel sınıftan türetilmiştir.Özel özniteliği, yalnızca C# içindeki Belirli türlere uygulanabilecek şekilde kısıtla?

Özel Özniteliğimi, yalnızca temel sınıfımdan türetilmesi gereken sınıflara uygulanabilmesi için nasıl kısıtlayabilirim? Bunu nasıl yaparım?

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; } 
} 

(orijinal cevap: Kendimi yanlış kanıtlamak zaman

+0

Bunu zorlamak (otomatik olarak yapılmak üzere) veya kısıtlamak mı istiyorsunuz (başka türlere uygulanamaz)? –

+0

Temel sınıfımdan türetilmeyenler dışındaki türlere uygulanmaması için onu kısıtlamak istiyorum. –

+0

Düzenleme: darn, Sanırım yapmam için bir yol bularak kendimle çeliştim! Benim için yeni bir tane ... –

cevap

15

Kahretsin, sen baz sınıfın bir korumalı iç içe türü olarak niteliği tanımlarsanız çalışır ... nefret

Bunu yapamazsınız - en azından derleme zamanında değil.

Öznitelikler "sınıf", "yapı", "yöntem", "alan" vb. Için sınırlandırılabilir (örneğin), ancak daha ayrıntılı bir şey olamaz.

Elbette, öznitelikler kendi başına hiçbir şey yapmadığı için (PostSharp'ı göz ardı ederek), diğer türlerde (ve çalışma zamanındaki özniteliklere bakmak için bir kod eklemediğiniz sürece türlerinizde etkisiz kalırlar) etkisiz kalırlar.

Bir FxCop kuralı yazabilirsiniz, ancak bu aşırı fazla gibi görünüyor.

Şimdi benim özel özellik uygulamak zorundadır tüm sınıfları tek temel sınıfından türetilen:

Ben bir özellik en iyi seçim olup olmadığını, ancak, merak ediyorum. onlar sizin özel özellik uygulamanız gerekir Eğer

, belki bir abstract (veya belki sadece virtual) özellik/yöntem daha iyi bir seçim olurdu?

abstract class MyBase { 
    protected abstract string GetSomeMagicValue {get;} 
} 
class MyActualType : MyBase { 
    protected override string GetSomeMagicValue {get {return "Foo";}} 
} 
+0

teşekkürler marc. Eşleme özelliklerine nitelik uygularıyorum. Temel sınıf bir yönteme, bu özniteliğin uygulandığı türetilmiş sınıftaki tüm özellikleri döndürür. Üstelik, bir öznitelik herhangi bir tür veya üyeye, önemli bir amaç olmadan uygulanmasına izin veren bir anlam yoktur. –

+0

Bunu yapmak için herhangi bir belge bulamadım bile, bir sonuca varmadan önce ona stackoverflow ile bir şans vermek istedim. Özniteliklerin maksatlı bir şekilde uygulandığına inanıyorum, bu yüzden neden bu tür veya amaç taşımayan üyelere uygulanmasına izin verin. –

+0

"Peki neden buna izin ver" - sadece şu anda onu engelleyemezsin. İzin vermeyecek bir mekanizma yoktur. –

0

Özel özniteliklerle bunu yapmanın hiçbir yolunun farkında değilim.
Daha iyi bir yol yüzden

class MyAttribute 
{ 
    // put whatever custom data you want in here 
} 

interface IAttributeService<T> where T : MyBaseClass 
{ 
    MyAttribute Value{get;} 
} 

ardından taban sınıfı derleyici olacak bu

class MyBaseClass : IAttributeService<MyBaseClass> 
{ 
    private MyAttribute m_attrib; 

    IAttributeService<MyClass>.Value 
    { 
     get {return m_attrib;} 
    } 
} 

O yolu yapacağını bir genel kısıtlaması

ile bir arabirim uygulamak sınıfları almak olacaktır Kısıtlama zamanında kısıtlamayı zorlayın, böylece MyBaseClass'dan türetilen yalnızca
sınıfları arabirimi uygulayabilir.
Ben MyAttribute sınıfı belirlenerek oldukça genişletilebilir yapılmış ama tabii sadece bu türetilmiş sınıfları göremiyorduk böylece basit bir şey

Ben de MyAttribute üye özel yapılmış gerekirse bir dize veya bir bool dönmek ve olabilir Değiştirin, ancak bunu korumak için korumalı hale getirebilir ve türetilmiş sınıflara erişime izin verebilir.