2012-05-04 3 views
1

私は、キーが私のMerchantIdであり、値が対応するTransactionKeyである列挙に、単一のキー/値ペア属性を付けるための最良の方法を見つけようとしています。単一のキーと値のペア属性を列挙に追加する最も良い方法は何ですか?

私は現在StringValueAttributeクラスにカンマ区切りの文字列を入れて何をすべきか:

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


を:.GetStringValue().Split(","c)(0)を呼び出して

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キーまたはを引き出します私は値を引き出すか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の何か?それとも、すでに効率的なのですか?

答えて

1

あなたが値を取得するには、以下のカスタム属性と拡張メソッドを使用することができます。注意すべきいくつかの点:

  • それは、C#でだが、それは大丈夫です願っています:)

  • 拡張メソッドクラスは静的スコープにMerchantIdsとTransactionIdsをキャッシュし、とてもきれい効率的でなければなりません。

  • 、たとえばMerchants.Coke.GetMerchantId();を呼び出してMerchantIdを取得します。

  • TransactionIdは、(、たとえばMerchants.Coke.GetTransactionId();を呼び出して取得します。あなたが((Merchants)76282).GetMerchantId()を呼び出すことによって、それを破ることができるように

また、拡張メソッドは、渡されたMerchants値が有効であることを確認する気にしないでください。

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

素敵な仕事!キャッシングとすべて:) –

+0

ありがとう:)私はこの種のことをかなりやっている自分自身を見つける... –

+0

これはまさに私が参照していたように見えますが、私はそれがエラーなしでVBに変換するように見えることができません。 。これらのコンバータはLINQがまだ好きではありません。 '.Select'メソッドがないので、CacheMerchantsCacheの' .Select'パーツにはまっています。 GetMerchantAttributeの '.GetCustomAttributes'と同じことです。 –

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 
+0

私はあなたが考えているものの例を見せてもらえますか? –

+0

http://www.codeguru.com/vb/gen/vb_general/attributes/article.php/c6073/Creating-and-Using-Custom-Attributes-with-VBNET.htmをご覧ください。 –

+0

私は分かりません。これは2003年に書かれたものです。そこより軽いものが必要です。私は効率についてここで話しています。 –

1

これからの来場者の皆様には、私が質問のタグ付けをしたので、私は答えのVB版を投稿すると思っていました。また、モジュール内に拡張機能が必要なため、少し違うことをやっていました。ここで

はモジュールです:

(私は読みやすくするために、行継続の多くを使用し、私はあることを入力する必要がないように。また、この例では、読みやすさのために、私は工assを輸入しました。ネームスペース)

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 
+1

+1 –

関連する問題