1

キーがMerchantIdで、値が対応するTransactionKeyである列挙に、単一のキーと値のペアの属性をアタッチするための最良の方法を見つけようとしています。

私が現在行っているのは、コンマ区切りの文字列をStringValueAttributeクラスに入れることです:

Public Enum Merchants
    <StringValue("coke,faj80785hq+faf=-1=-jfa+">
        Coke = 0
    <StringValue("pepsi,adfji=-901jnas++fdj98ua")>
        Pepsi = 1
    <StringValue("drpepper,jk878-=+9kdkdja0=a=f--daj")>
        DrPepper = 2
End Enum

Public Property Merchant As Merchants


次のように呼び出し て、キーまたはMerchantId.GetStringValue().Split(","c)(0)を取り出します。

Public ReadOnly Property MerchantId() As String
    Get
        Return Merchant.GetStringValue().Split(","c)(0)
    End Get
End Property


次のように呼び出し て、値またはTransactionKey.GetStringValue().Split(","c)(1)を取り出します。

Public ReadOnly Property TransactionKey() As String
    Get
        Return Merchant.GetStringValue().Split(","c)(1)
    End Get
End Property

これはこれを行う最も効率的な方法ですか?の代わりに、キーと値のペアのリストでStringValueAttributeあるため、 を使用して属性を作成するのはどうですか? Dictionary(Of String, String)または文字列配列またはリスト?多分LINQの何か?それとも、可能な限りすでに効率的ですか?

4

3 に答える 3

1

タイプセーフな方法で両方の値を取り、適切に名前を付ける独自の属性クラスを作成することをお勧めします。または、すべてのアイテムが両方の値を持つわけではない場合は、値ごとに 1 つずつ、2 つの別個の属性を作成します。

または、さらに良いことに、Enum をまったく使用しないでください。コンストラクターで 3 つの値すべてを受け取る独自のクラスを作成し、次に各項目の共有プロパティを持つクラスを作成します。

Public Class Merchants
    Public Shared ReadOnly Property Coke() As Merchant
        Get
            Return _coke
        End Get
    End Property
    Private Shared _coke = New Merchant(0, "Coke", "faj80785hq+faf=-1=-jfa+")

    ...
End Class
于 2012-05-04T14:24:12.020 に答える
1

将来の訪問者のために、質問にタグを付けたものであるため、回答のVBバージョンを投稿すると思いました。また、VB では拡張機能がモジュール内にある必要があるため、少し異なることをしなければなりませんでした。

モジュールは次のとおりです。

(読みやすくするために多くの行継続を使用しました。また、この例では読みやすくするために、NameSpace を入力する必要がないように SomeClass をインポートしました)

Imports SomeClass

Module MerchantsExtensions

    Private ReadOnly MerchantsCache _
        As Dictionary(Of Merchants, MerchantDataAttribute) _
        = CacheMerchantsCache()

    Private Function CacheMerchantsCache() _
        As Dictionary(Of Merchants, MerchantDataAttribute)

        Return [Enum].GetValues(GetType(Merchants)) _
            .Cast(Of Merchants)() _
            .Select(Function(m) New With
            {
                .Merchant = m,
                .MerchantAttribute = GetMerchantAttribute(m)
            }) _
            .ToDictionary(Function(m) m.Merchant, _
                          Function(m) m.MerchantAttribute)

    End Function

    Private Function GetMerchantAttribute(merchant As Merchants) _
        As MerchantDataAttribute

        Return GetType(Merchants) _
            .GetMember(merchant.ToString()) _
            .First() _
            .GetCustomAttributes(GetType(MerchantDataAttribute), _
                                 inherit:=False) _
            .Cast(Of MerchantDataAttribute)() _
            .First()

    End Function

    <Runtime.CompilerServices.Extension()>
    Public Function GetMerchantId(merchants As Merchants) As String

        Return MerchantsCache(merchants).Id

    End Function

    <Runtime.CompilerServices.Extension()>
    Public Function GetTransactionKey(merchants As Merchants) As String

        Return MerchantsCache(merchants).TransactionKey

    End Function

End Module


SomeClassこの例のため に私が名前を付けたクラスの拡張メソッドの実装を次に示します。

Public Class SomeClass

    Public Enum Merchants
        <MerchantData("coke", "faj80785hq+faf=-1=-jfa+")>
            Coke = 0
        <MerchantData("pepsi","adfji=-901jnas++fdj98ua")>
            Pepsi = 1
        <MerchantData("drpepper","jk878-=+9kdkdja0=a=f--daj")>
            DrPepper = 2
    End Enum

    <AttributeUsage(AttributeTargets.Field)>
    Public Class MerchantDataAttribute : Inherits Attribute

        Public Sub New(merchantId As String, transactionKey As String)
            _Id = merchantId
            _TransactionKey = transactionKey
        End Sub

        Public Property Id() As String
        Public Property TransactionKey() As String

    End Class

End Class
于 2012-05-04T20:54:35.317 に答える
1

次のカスタム属性と拡張メソッドを使用して、値を取得できます。注意すべき点:

  • これは C# です。問題ないことを願っています :)

  • 拡張メソッド クラスは MerchantIds と TransactionIds を静的スコープにキャッシュするので、かなり効率的です。

  • MerchantIdを呼び出すことで取得できます( eg ) Merchants.Coke.GetMerchantId();

  • TransactionIdを呼び出すことで取得できます( eg ) Merchants.Coke.GetTransactionId();

また、拡張メソッドは、渡された値が有効であることをわざわざチェックしないMerchantsため、 を呼び出すことでそれを壊すことができます((Merchants)76282).GetMerchantId()

[AttributeUsage(AttributeTargets.Field)]
public class MerchantDataAttribute : Attribute
{
    public MerchantDataAttribute(string merchantId, string transactionId)
    {
        this.MerchantId = merchantId;
        this.TransactionId = transactionId;
    }

    public string MerchantId
    {
        get;
        private set;
    }

    public string TransactionId
    {
        get;
        private set;
    }
}

public static class MerchantsExtensions
{
    private static readonly Dictionary<Merchants, MerchantDataAttribute> 
        _merchantsCache = CacheMerchantsCache();

    public static string GetMerchantId(this Merchants merchants)
    {
        return _merchantsCache[merchants].MerchantId;
    }

    public static string GetTransactionId(this Merchants merchants)
    {
        return _merchantsCache[merchants].TransactionId;
    }

    private static Dictionary<Merchants, MerchantDataAttribute> CacheMerchantsCache()
    {
        return Enum.GetValues(typeof(Merchants))
            .Cast<Merchants>()
            .Select(m => new
            {
                Merchant = m, 
                MerchantAttribute = GetMerchantAttribute(m)
            })
            .ToDictionary(m => m.Merchant, m => m.MerchantAttribute);
    }

    private static MerchantDataAttribute GetMerchantAttribute(Merchants merchant)
    {
        return typeof(Merchants)
            .GetMember(merchant.ToString())
            .First()
            .GetCustomAttributes(typeof(MerchantDataAttribute), inherit: false)
            .Cast<MerchantDataAttribute>()
            .First();
    }
}
于 2012-05-04T15:02:44.450 に答える