代码之家  ›  专栏  ›  技术社区  ›  user153498

C#属性-数组还是重复?

  •  1
  • user153498  · 技术社区  · 16 年前

    我正在用C#创建一个网络聊天客户端,作为一个辅助项目。除了简单的文本消息外,我还可以在输入文本框中输入带有斜杠前缀的命令。我使用了模块化方法,创建了一个包含所有各种命令的枚举,然后用属性装饰这些命令。

    例子:

    public enum CommandType : byte
    {
        [PrimaryIdentifier("file"),
         AdditionalIdentifier("f"),
         CommandUsage("[<recipient>] [<filelocation>]")]
        FileTransferInitiation,
    
        [PrimaryIdentifier("accept"),
         AdditionalIdentifier("a")]
        AcceptFileTransfer,
    
        // ...
    }
    

    当我尝试允许主命令使用多个别名时,问题就出现了。我尝试了两种方法:允许复制 AdditionalIdentifier 属性,或通过在 附加标识符 params string[]

    对于前者,我通过使用 AttributeUsage 和背景 AllowMultiple 这是真的。虽然这确实达到了我想要的效果,但我觉得除了其他属性之外,如果有几行别名,可能会很快变得非常嘈杂。

    compiler warning CS3016

    非常感谢。

    4 回复  |  直到 16 年前
        1
  •  1
  •   itowlson    16 年前

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

    缺点是,这会将您限制在预先确定的标识符数量内。

    编辑: 进一步考虑一下,这些枚举上有很多属性。您可能需要考虑创建一个抽象命令类,并将标识符、用法等暴露为该类的属性;然后派生从这些属性返回适当值的具体命令类型。这可能还允许您将处理逻辑移动到这些命令对象中,而不是打开枚举值。

        2
  •  2
  •   RussTheAerialist    16 年前

    您还可以在构造函数中使用“params string[]别名”来允许变量参数列表:

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

    这将允许您执行以下操作:

    [Test("test1", "test2", "test3")]
    static void Main(string[] args)
    
        3
  •  1
  •   tvanfosson    16 年前

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

    然后像这样使用它:

    public enum CommandType : byte
    {
         [Identifer( Name = "file", Aliases = "f", Usage = "..." )]
         FileTransferType,
    
         ...
    }
    
        4
  •  0
  •   Dan Blanchard    16 年前

    还有另一种方法是让属性将字符串数组作为构造函数参数-这样,您就可以让编译器为您解析数组(在应用属性时会有一点麻烦),因此:

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

    一个实施&使用这样的技术如下所示:

    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);
                }
            }
        }
    }
    
    推荐文章