Frage

Ich bin erstellen einer Netzwerk-chat-client in C# as a side project.Neben einfachen text-Nachrichten, ich habe auch slash-Präfix-Befehle, die eingegeben werden kann in das Eingabe-Textfeld ein.Ich verwendet einen modularen Ansatz, durch das anlegen eines enum enthält die verschiedenen Befehle, und dann dekorieren Sie diese Befehle mit Parametern.

Die Attribute angeben, was Schrägstrich vorangestellt Befehl kann eingegeben werden, um den Befehl auslösen, sowie alle Aliase der primäre Befehls-id und das Kommando zu nutzen ist.

Beispiel:

public enum CommandType : byte
{
    [PrimaryIdentifier("file"),
     AdditionalIdentifier("f"),
     CommandUsage("[<recipient>] [<filelocation>]")]
    FileTransferInitiation,

    [PrimaryIdentifier("accept"),
     AdditionalIdentifier("a")]
    AcceptFileTransfer,

    // ...
}

Mein problem entsteht, wenn ich versuche, es erlauben, mehrere Aliase, um den primären Befehl.Ich habe versucht, diese zwei Möglichkeiten:indem Sie Duplikate von den AdditionalIdentifier Attribut, oder indem Sie den Konstruktor als argument in AdditionalIdentifier ein params string[].

Mit der ehemaligen, die ich umgesetzt habe, es zu dekorieren, das Attribut der Klasse mit AttributeUsage und Einstellung AllowMultiple zu wahren.Während dies tatsächlich erreichen, was ich Suche, ich fühle mich wie es könnte wirklich laut, die wirklich schnell mehrere Zeilen Aliase, zusätzlich zu den anderen Parametern.

Letzteres funktioniert auch, allerdings erzeugt es die compiler-Warnung CS3016, und sagt, daß dieser Ansatz ist nicht CLS-kompatibel.Natürlich, dies bedeutet nicht unbedingt aufhören, mich von der immer noch mit ihm, aber ich habe gelernt, immer Warnungen als Fehler behandeln.

Meine eigentliche Frage ist, sollte ich Ignoriere meine Einwände mit Duplikaten und einfach gehen Sie voran und verwenden Sie Sie, oder gibt es eine andere Lösung, die verwendet werden könnten?

Danke.

War es hilfreich?

Lösung

Persönlich würde ich mit dem AllowMultiple Ansatz gehen: Ich glaube nicht, das „Rauschen“, dass ein großes Problem sein wird, es sei denn, Sie wirklich LKW-Ladungen von Kennungen für jeden Befehl haben. Aber wenn Sie möchten nicht, dass und wollen CLS-kompatibel bleiben, eine andere Lösung wäre ladenen Konstruktoren zur Verfügung zu stellen für AdditionalIdentifierAttribute:

public AdditionalIdentifierAttribute(string id) { ... }
public AdditionalIdentifierAttribute(string id1, string id2) { ... }
public AdditionalIdentifierAttribute(string id1, string id2, string id3) { ... }

Der Nachteil ist, dass diese Sie nicht begrenzt auf eine vorbestimmte Anzahl von Identifikatoren.

Das heißt, CLS-Kompatibilität ist wirklich nur ein wichtiger Aspekt, wenn Sie eine Bibliothek erstellen, die andere sind wahrscheinlich zu verwenden (und insbesondere aus anderen Sprachen). Wenn diese Art oder die Bibliothek zu Ihrer Anwendung intern ist, dann ist es sinnvoll CLS-Kompatibilität Warnungen zu ignorieren.

EDIT: Weiter denken darüber, Sie haben ziemlich viele Attribute auf diesen Aufzählungen. Sie könnten eine abstrakte Command Klasse zu schaffen, anstatt prüfen möchten, und Aussetzen der Identifikatoren, Nutzung, usw. als Eigenschaften dieser Klasse; dann leitet konkrete Arten von Befehl, die die entsprechenden Werte aus diesen Eigenschaften zurückzukehren. Dies möglicherweise auch ermöglicht es Ihnen, die Handhabung Logik in diese Befehlsobjekte zu bewegen, anstatt auf dem ENUM-Wert umgeschaltet wird.

Andere Tipps

Sie können auch "params string [] Aliases" im Konstruktor verwenden eine variable Argumentliste zu ermöglichen:

[AttributeUsage(AttributeTargets.Method)]
class TestAttribute : Attribute
{
    public TestAttribute(params string[] aliases)
    {
        allowedAliases = aliases;
    }

    public string[] allowedAliases { get; set; }

}

Auf diese Weise könnten Sie tun:

[Test("test1", "test2", "test3")]
static void Main(string[] args)

Warum nicht ein einzelnes Attribut mit mehreren Eigenschaften?Haben die Eigenschaft, für die alias-nehmen Sie eine durch Kommas getrennte Liste.Dies ist der Ansatz, den Sie nehmen in MVC für Dinge wie das AuthorizeAttribute für Rollen.Intern wird die Eigenschaft analysiert die Zeichenfolge in ein array für die einfache Anwendung in der Attribut-Klasse, aber es erlaubt Ihnen eine einfache Möglichkeit, um Ihre Konfiguration.

public class IdentifierAttribute
{
    public string Name { get; set; }
    public string Usage { get; set; }

    private string[] aliasArray;
    private string aliases;
    public string Aliases
    {
         get { return this.aliases; }
         set
         {
             this.aliases = value;
             this.aliasArray = value.Split(',').Trim();
         }
    }
}

Dann benutze es wie:

public enum CommandType : byte
{
     [Identifer( Name = "file", Aliases = "f", Usage = "..." )]
     FileTransferType,

     ...
}

Ein weiterer Ansatz wäre das Attribut nehmen ein Array von Strings als Konstruktor Parameter haben sein - diese Weise erhalten Sie die Compiler das Array für Sie (auf Kosten von etwas mehr goop, wenn das Attribut Anwendung) zu analysieren, damit :

[Identifiers(new string[] {"Bill", "Ben", "Ted"})]

Eine schnelle ‚n schmutzig Beispiel für die Umsetzung und den Einsatz einer solchen Technik sieht wie folgt aus:

using System;
using System.Collections.ObjectModel;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            SomeClass.TellMeAboutYourself();
        }
    }
    public class Identifiers : Attribute
    {
        private string[] names;
        public Identifiers(string[] someNames)
        {
            names = someNames;
        }
        public ReadOnlyCollection<string> Names { get { return new ReadOnlyCollection<string>(names); } }
    }
    [Identifiers(new string[] {"Bill", "Ben", "Ted"})]
    static class SomeClass
    {
        public static void TellMeAboutYourself()
        {
            Identifiers theAttribute = (Identifiers)Attribute.GetCustomAttribute(typeof(SomeClass), typeof(Identifiers));
            foreach (var s in theAttribute.Names)
            {
                Console.WriteLine(s);
            }
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top