문제

C#에서 사이드 프로젝트로 네트워크 채팅 클라이언트를 만들고 있습니다. 간단한 문자 메시지 외에도 입력 텍스트 상자에 입력 할 수있는 슬래시 준비된 명령도 있습니다. 모든 다양한 명령이 포함 된 열거를 만들고 속성으로 해당 명령을 장식하여 모듈 식 접근법을 사용했습니다.

속성은 명령을 트리거하기 위해 Slash-Prefixed 명령을 입력 할 수있는 항목 및 기본 명령 식별자 및 명령의 사용법에 대한 별칭을 지정합니다.

예시:

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

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

    // ...
}

여러 별칭을 기본 명령에 허용하려고 할 때 문제가 발생합니다. 나는이 두 가지 방법을 시도했다 : AdditionalIdentifier 속성, 또는 생성자 인수를 작성함으로써 AdditionalIdentifierparams string[].

전자와 함께, 나는 속성 클래스를 AttributeUsage 그리고 설정 AllowMultiple 사실. 이것이 실제로 내가 찾고있는 것을 달성하지만, 다른 속성 외에도 여러 줄의 별명을 갖는 것이 실제로 시끄럽게 될 수 있다고 생각합니다.

후자는 또한 작동하지만 컴파일러 경고 CS3016, 그리고 그 접근법은 CLS를 준수하지 않는다고 말합니다. 분명히, 이것이 여전히 그것을 사용하는 것을 막을 수는 없지만, 나는 항상 경고를 오류로 취급하는 법을 배웠습니다.

내 실제 질문은 복제물로 이의 제기를 무시하고 계속 사용해야합니까, 아니면 사용할 수있는 다른 솔루션이 있습니까?

고맙습니다.

도움이 되었습니까?

해결책

개인적으로 나는 허용 다중 접근 방식과 함께 갈 것입니다. 각 명령에 대한 트럭로드가 실제로 없다면 "소음"이 그다지 문제가 될 것이라고 생각하지 않습니다. 그러나 당신이 그것을 좋아하지 않고 CLS 호환을 유지하고 싶다면 다른 솔루션은 추가 식별자를 위해 과부하 된 생성자를 제공하는 것입니다.

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

단점은 이것이 미리 정해진 수의 식별자로 제한한다는 것입니다.

즉, CLS 규정 준수는 다른 사람들이 사용할 수있는 라이브러리 (특히 다른 언어에서)를 구축하는 경우 실제로 큰 고려 사항 일뿐입니다. 이 유형 또는 라이브러리가 응용 프로그램 내부 인 경우 CLS 준수 경고를 무시하는 것이 합리적입니다.

편집하다: 이것에 대해 더 생각하면, 당신은 그 열거에 대해 많은 속성을 가지고 있습니다. 대신 추상 명령 클래스를 만들고 식별자, 사용법 등을 해당 클래스의 속성으로 노출시키는 것을 고려할 수 있습니다. 그런 다음 해당 속성에서 적절한 값을 반환하는 구체적인 유형의 명령을 도출하십시오. 이를 통해 열거 값을 켜지 않고 처리 로직을 해당 명령 개체로 이동할 수 있습니다.

다른 팁

생성자에서 "params string [] aliases"를 사용하여 변수 인수 목록을 허용 할 수도 있습니다.

[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)

여러 속성을 가진 단일 속성이없는 이유는 무엇입니까? 별칭의 속성이 쉼표로 구분 된 목록을 가져 오도록하십시오. 이것은 역할에 대한 승인을 위해 MVC에서 취하는 접근법입니다. 내부적으로 속성은 속성을 속성 클래스에서 쉽게 사용할 수 있도록 배열로 문자열을 구문 분석하지만 구성을 쉽게 설정할 수 있습니다.

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,

     ...
}

또 다른 접근법은 속성이 문자열 배열을 생성자 매개 변수로 취하는 것입니다. 그렇게하면 컴파일러가 배열을 구문 분석 할 수 있습니다 (속성을 적용 할 때 조금 더 goop을 희생하면).

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

이러한 기술을 구현하고 사용하는 빠른 'N Dirty 예제는 다음과 같습니다.

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);
            }
        }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top