Vra

EDIT: Ek wil 'n beter herformuleer: Hoe kan ek die AOO-implementering van 'n klas eiendom te skuif na 'n / die gebruik van 'n persoonlike kenmerk? (Ek het bygevoeg instantation Vars (classname, propertyname) om die eienskap, maar ek wil eerder hierdie outomaties haal natuurlik.)

Public Class CustomClass
    <CustomAttributeClass(ClassName:="CustomClass", PropertyName = "SomeProperty")> _
    Public Property SomeProperty() as String
        Get() as String
            //This implementation should be handled by the attribute class
        End Get

        Set(Byval value as String)
            Me._someProperty = value
        End Set
    End Property
End Class

Old vraag:

Ek wil 'n persoonlike eiendom kenmerk vir klasse te skep. Ek kan 'n klas afgelei van Kenmerk, en 'n punt 'die eiendom met die kenmerk te skep, maar waar om te gaan van hier af?

Ek het 'n bron waar ek vinnig data wat gebaseer is op die eienskappe waardes kan kry. Ek wil graag die gedrag van die eiendom in die kenmerk veralgemeen, maar ek weet nie hoe om te gaan van hier af ... Enige hulp sal grootliks aanvaar word!

Public Class CustomDataAttribute : Inherits Attribute
    Private _name As String

    Public Sub New(ByVal name As String)
        Me.Name = name
    End Sub

    Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            Me._name = value
        End Set
    End Property
End Class


Public Class CustomClass
    <CustomDataAttribute(Name:="CustomField")> _ 
    Public Property CustomField()
    End Property
End Class
Was dit nuttig?

Oplossing

Jy sal hê om te Refleksie gebruik om die kenmerk te ontdek. In jou geval, sal jy dit kry van PropertyInfo.GetCustomAttributes ().

Die harder deel van die gebruik eienskappe is om 'n geskikte uitvoering model om hulle eintlik gebruik. Iets soos 'n samesteller, 'n ontwerper of 'n klas wat voorwerpe serializes is 'n ooglopende een. Die bruikbaarheid van eienskappe spirale vinnig af van daar af. Dit is byna altyd die verkeerde keuse wanneer jy probeer om 'n kenmerk waar 'n virtuele eiendom eintlik nodig gebruik. Herwinning van kenmerk waardes is baie duur, baie ordes duurder as die herwinning van 'n eiendom se waarde. Gebruik dit net vir die weerspieëling kode lopies teen menslike tyd (soos opstellers) of wanneer die koste is onbelangrik in vergelyking met die voordeel of die oorhoofse (algemeen in enige vorm van I / O operasie).

Ander wenke

Van jou kommentaar aan die vorige antwoord, ek dink jy sal vind dat NET eienskappe is nie heeltemal so buigsaam soos jy wil hê hulle moet wees.

Jy het gevra "Is daar nie 'n paar basis eiendom-kenmerk wat sommige gebeurtenisse soos onGet en begin het?" -- geen; eienskappe het geen ingeboude interaksie met hul teikens, of metodes of klasse. In feite, kan jy nie eens vertel tydens looptyd wat die teiken van 'n kenmerk is; jy moet die teiken (klas, metode, eiendom ens) weet eerste en dan navraag wat kenmerke versier dit.

In die tweede plek, kenmerke is nie eintlik geskep totdat jy navraag vir hulle. Wanneer jy GetCustomAttributes noem, die runtime stelsel evalueer die vergadering metadata en instantiates die eienskappe wat vermeld. As jy dit twee keer bel in 'n ry, sal jy twee stelle van dieselfde eienskappe kry.

Gaan terug na jou ander vraag: as jy wil weet wanneer 'n eiendom versier met jou eienskappe is ingestel of opgespoor, jy wil hê om INotifyPropertyChanged implementeer op al jou verwante klasse, Skryf kode om al jou klasse vir goedere soek gemerk met daardie eienskap op vergadering vrag, en dan bou sommige interaktiwiteit wat gekoppel die PropertyChanged gebeure vir alles-kode wat jy nodig het om te vuur. (En dit net in kennis stel oor set bedrywighede, nie get.)

Geen idee as dit nuttig, maar daar gaan jy. : -)

Hier is 'n klas wat help verwerk persoonlike eienskappe by die gebruik van nadenke. Slaag die tipe as 'n parameter na contructor.

public class AttributeList : List<Attribute>
{
    /// <summary>
    /// Gets a list of custom attributes
    /// </summary>
    /// <param name="propertyInfo"></param>
    /// <returns></returns>
    public static AttributeList GetCustomAttributeList(ICustomAttributeProvider propertyInfo)
    {
        var result = new AttributeList();
        result.AddRange(propertyInfo.GetCustomAttributes(false).Cast<Attribute>());
        return result;
    }

    /// <summary>
    /// Finds attribute in collection by its own type or parents type
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T FindAttribute<T>() where T : Attribute
    {
        return (T)Find(x => typeof(T).IsAssignableFrom(x.GetType()));
    }

    /// <summary>
    /// Finds attribute in collection by its own type or parents type
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public List<T> FindAllAttributes<T>() where T : Attribute
    {
        return new List<T>(FindAll(x => typeof(T).IsAssignableFrom(x.GetType())).Cast<T>());
    }

    /// <summary>
    /// Finds attribute in collection by its own type or parents type
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public List<T> FindAllAttributes<T>(Type implementsType) where T : Attribute
    {
        return new List<T>(FindAll(x => implementsType.IsAssignableFrom(x.GetType())).Cast<T>());
    }

    public bool IsAttributeSet<T>() where T : Attribute
    {
        return FindAttribute<T>() != null;
    }

    public TValue GetValueFromAttributeOrDefault<TAttr, TValue>(Func<TAttr, TValue> func, TValue defaultValue) 
        where TAttr : Attribute
    {
        var attribute = FindAttribute<TAttr>();
        return attribute == null ? 
            defaultValue : 
            func(attribute);
    }
}

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top