我正在尝试找出将单个键/值对属性附加到枚举的最佳方法,其中键是 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
我通过拨打.GetStringValue().Split(","c)(0)
来取出密钥或 MerchantId :
Public ReadOnly Property MerchantId() As String
Get
Return Merchant.GetStringValue().Split(","c)(0)
End Get
End Property
我通过调用.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中的东西?或者它是否已经很有效率了?
答案 0 :(得分:1)
我建议您创建自己的属性类,它以类型安全的方式获取这两个值并适当地命名它们。或者,如果不是每个项目都具有两个值,则创建两个单独的属性,每个值对应一个值。
或者更好的是,根本不要使用Enum。创建自己的类,在构造函数中获取所有三个值,然后为每个项创建一个具有共享属性的类,如下所示:
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
答案 1 :(得分:1)
您可以使用以下自定义属性和扩展方法来获取值。有些事情需要注意:
它在C#中,希望没问题:)
扩展方法类将MerchantIds和TransactionIds缓存在静态范围内,因此效率非常高。
您通过致电(例如)MerchantId
获得Merchants.Coke.GetMerchantId();
。
您通过致电(例如)TransactionId
获得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();
}
}
答案 2 :(得分:1)
对于任何未来的访问者,我想我会发布答案的VB版本,因为那是我用这个问题标记的。此外,由于VB要求扩展在模块内部,我不得不做一些稍微不同的事情。
以下是模块:
(为了便于阅读,我使用了很多行继续。另外,为了便于阅读,我在本例中导入了SomeClass,因此我没有输入NameSpace)
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
的类I中的扩展方法的实现:
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