Angenommen, ich eine Klasse wie diese:Wie verwende ich C# -Attribute, um eine Methode in einer Klasse basierend auf einer Zeichenfolge auszuwählen?
public class MyMethods
{
[SpecialMethod("test")]
public string GetTestString(int i)
{
return string.Format("Hello world {0} times!",i);
}
[SpecialMethod("lorem")]
public string GetSomeLoremIpsumText(int i)
{
// ignores the 'i' variable
return "Lorem ipsum dolor sit amet";
}
// ... more methods with the same signature here ...
public string DefaultMethod(int i)
{
return "The default method happened! The attribute wasn't found.";
}
public string ThisMethodShouldNotShowUpViaAttributes(int i)
{
return "You should not be here.";
}
}
Ich habe auch das Attribut einfach wie folgt definiert:
[AttributeUsage(AttributeTargets.Method)]
public class SpecialMethodAttribute : System.Attribute
{
private string _accessor;
public string Accessor
{
get
{
return _accessor;
}
}
public SpecialMethodAttribute(string accessor)
{
_accessor = accessor;
}
}
Was ich so in der Lage sein zu tun aussehen könnte:
public class MethodAccessViaAttribute
{
private MyMethods _m;
public MethodAccessViaAttribute()
{
_m = new MyMethods();
}
public string CallMethodByAccessor(string accessor, int i)
{
// this is pseudo-code, expressing what I want to be able to do.
Func<int, string> methodToCall = FindAMethodByAttribute(_m, accessor);
if (methodToCall == null)
return _m.DefaultMethod(i);
else
return methodToCall(i);
}
public void Test()
{
// should print "Hello world 3 times!"
Console.WriteLine(CallMethodByAccessor("test",3));
// should print "Lorem ipsum dolor sit amet"
Console.WriteLine(CallMethodByAccessor("lorem",int.MaxValue));
// should print "The default method happened! The attribute wasn't found."
Console.WriteLine(CallMethodByAccessor("I-do-not-exist",0));
}
}
Beachten Sie, dass alle Methoden der SpecialMethod
die gleiche Methode Unterschrift folgen Attribut. Idealerweise würde die Suchfunktion Methoden ausschließen, die nicht mit der Signatur übereinstimmen, da ein try/catch
verwendet werden könnte, um zu testen, ob die Methode mit der Signatur Func
übereinstimmt.
Kann ich einen Punkt in der richtigen Richtung, wie dies zu erreichen?
Es klingt für mich wie Sie diesen Ansatz überdenken sollten. Sie könnten auch einen Switch Case in einer einzigen Methode basierend auf dem "Accessor" Wort stecken. Sie können dies auf verschiedene Arten anders als durch Attribute erreichen. Ich bin neugierig, was ist der Anwendungsfall für solchen Code? – JuanR
Ich schreibe eine Bibliothek, die ich in ein anderes Projekt importieren möchte. Daher ist die Hardcodierung der Fälle nicht akzeptabel. Ich möchte in der Lage sein, eine neue mögliche Methode einfach hinzuzufügen, indem ich eine neue Methode mit der richtigen Signatur und dem entsprechenden Attribut hinzufüge. Da .NETs eigenes Komponententest grundsätzlich einen Ansatz wie diesen verwendet, der Methoden bezeichnet, die mit [TestMethod] aufgerufen werden sollten, nehme ich an, dass es einen Weg gibt, dies zu erreichen. – fdmillion
Ich schlage vor, dass Sie in Schnittstellen schauen (Denken Sie Plugin-Muster). Ich würde eine Schnittstelle erstellen, die das Objekt darstellt, das die betreffende Methode implementiert. Ich kann dann die Assembly laden und nach Klassen suchen, die diese Schnittstelle implementieren, sie instanziieren und die Methode aufrufen. – JuanR