24 Stimmen

Abfrage des Mitglieds, auf das das Attribut innerhalb des Attributkonstruktors angewendet wurde?

Ich habe ein benutzerdefiniertes Attribut, im Konstruktor meines benutzerdefinierten Attributs möchte ich den Wert einer Eigenschaft meines Attributs auf den Typ der Eigenschaft setzen, auf die mein Attribut angewendet wurde, gibt es eine Möglichkeit, auf das Mitglied zuzugreifen, auf das das Attribut von innerhalb meiner Attributklasse angewendet wurde?

0 Stimmen

Können Sie den Anwendungsfall kurz beschreiben?

1 Stimmen

Wenn Sie das Problem, das Sie lösen wollen, genauer beschreiben können, ist es vielleicht möglich, eine alternative Lösung anzubieten.

1 Stimmen

Danke, ich weiß, wie ich das Gleiche auf andere Weise erreichen kann, aber ich wollte wissen, ob dies möglich ist, weil der Code sauberer wäre.

20voto

Niels Filter Punkte 4247

Es ist möglich von .NET 4.5 mit CallerMemberName :

[SomethingCustom]
public string MyProperty { get; set; }

Dann Ihr Attribut:

[AttributeUsage(AttributeTargets.Property)]
public class SomethingCustomAttribute : Attribute
{
    public StartupArgumentAttribute([CallerMemberName] string propName = null)
    {
        // propName == "MyProperty"
    }
}

1 Stimmen

Dies sollte jetzt die markierte Antwort sein! Genau das, was ich brauchte, danke!

2 Stimmen

Dies wurde schon vor einiger Zeit hinzugefügt, aber ich habe eine Folgefrage: Diesem Link zufolge [ learn.microsoft.com/de-us/dotnet/csharp/programming-guide/ [CallerMemberName] gibt nur den Namen des Mitglieds an, nicht in voll qualifizierter Form. Wenn ich also diesen Typ über Reflection abrufen möchte, wie kann ich dann seinen vollständigen Namen erfahren?

0 Stimmen

Es gibt derzeit keine Alternative, um die Art des Anrufs zu erhalten. Hoffentlich wird dies bald möglich sein. Siehe Diskussion hier: github.com/dotnet/csharplang/diskussionen/87

18voto

Paul Turner Punkte 37044

Ich fürchte, so funktionieren Attribute nicht. Sie sind lediglich "Markierungen", die mit Objekten verbunden sind, aber nicht mit ihnen interagieren können.

Attribute selbst sollten in der Regel kein Verhalten aufweisen und lediglich Metadaten für den Typ enthalten, dem sie zugeordnet sind. Jegliches Verhalten, das mit einem Attribut verbunden ist, sollte von einer anderen Klasse bereitgestellt werden, die das Vorhandensein des Attributs prüft und eine Aufgabe ausführt.

Wenn Sie sich für den Typ interessieren, auf den das Attribut angewandt wird, sind diese Informationen zur gleichen Zeit verfügbar, in der Sie nach dem Attribut suchen.

0 Stimmen

Wie Sie sagen, ist es nicht das Ende der Welt, da Sie den Typ kennen, wenn Sie das benutzerdefinierte Attribut über Reflection erhalten, aber es wäre "schön", wenn der Typ, der an GetCustomAttribute übergeben wird, auch in System.Attribute gespeichert würde.

0voto

Klyuch Punkte 66

Das können Sie als nächstes tun. Es ist ein einfaches Beispiel.

//target class
public class SomeClass{

    [CustomRequired(ErrorMessage = "{0} is required", ProperytName = "DisplayName")]
    public string Link { get; set; }

    public string DisplayName { get; set; }
}
    //custom attribute
    public class CustomRequiredAttribute : RequiredAttribute, IClientValidatable
{
    public string ProperytName { get; set; }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var propertyValue = "Value";
        var parentMetaData = ModelMetadataProviders.Current
             .GetMetadataForProperties(context.Controller.ViewData.Model, context.Controller.ViewData.Model.GetType());
        var property = parentMetaData.FirstOrDefault(p => p.PropertyName == ProperytName);
        if (property != null)
            propertyValue = property.Model.ToString();

        yield return new ModelClientValidationRule
        {
            ErrorMessage = string.Format(ErrorMessage, propertyValue),
            ValidationType = "required"
        };
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X