我正在编写REST API的包装器。因此,每当我从服务器检索项目时,我只需要使用参数(在uri中)。我现在这样做的方式工作得很好,但我觉得必须有另一种优雅的方式,可能用enum
或其他东西。
我不喜欢我需要'知道'Dictionary
类型为string
的选项是什么。我尝试使用Dictionary<EnumType, string>
,但我有多种enum
。另外,我不确定如何将EnumType
(键)映射到适当的值。
基本上,我尽量避免使用magic关键字。
这是我的部分代码:
public string GetUnreadItems()
{
var options = new Dictionary<string, string>();
options.Add("ItemType", "Unread");
options.Add("SortBy", "Latest");
// GetItemsBasedOn(options);
}
public string GetAllItems()
{
var options = new Dictionary<string, string>();
options.Add("ItemType", "All");
// GetItemsBasedOn(options);
}
public string GetItemsBasedOn(Dictionary<string, string> options)
{
// Do request here based on options passed
// and return the result to caller function
}
编辑: 这就是我想要实现的http://getpocket.com/developer/docs/v3/retrieve
我想实施选项sort
,detailType
,contentType
,Favorite
和State
。每个选项都有自己的选项,但一次只能选择一个。
答案 0 :(得分:2)
有几种方法可以改善您当前的设计。我不同意我要向您呈现的解决方案是理想的解决方案,但鉴于您已经确定您想要使用enum
,我认为您将满足于此解决方案。
您可以做的是定义标有enum
属性的[Flags]
。为枚举中的每个标志分配一个2的幂。如果要组合选项以创建单个选项,请使用bitwise or,就像我在前面的示例中使用名为“All”的标志一样:
[Flags]
public enum GetItemOptions
{
Read = 0x1,
Unread = 0x2,
All = 0x1 | 0x2,
SortByOldest = 0x4,
SortByLatest = 0x8
}
从您的代码示例中,第一个调用现在将如下所示:
GetItemsBasedOn(GetItemOptions.Unread | GetItemOptions.SortByLatest);
第二个看起来像这样:
GetItemsBasedOn(GetItemOptions.All);
为了启用此设计,您需要调整GetItemsBasedOn
方法签名,以便它指定GetItemOptions
枚举类型的参数。以下是如何处理不同设置的示例。
public static void GetItemsBasedOn(GetItemOptions getItemOption)
{
if (getItemOption.HasFlag(GetItemOptions.SortByOldest) && getItemOption.HasFlag(GetItemOptions.SortByLatest))
throw new ArgumentException("I can't sort by both...");
if (getItemOption.HasFlag(GetItemOptions.Read))
{
Console.WriteLine("READ");
}
if (getItemOption.HasFlag(GetItemOptions.Unread))
{
Console.WriteLine("UNREAD");
}
if (getItemOption.HasFlag(GetItemOptions.SortByOldest))
{
Console.WriteLine("SORT BY OLDEST");
}
else if (getItemOption.HasFlag(GetItemOptions.SortByLatest))
{
Console.WriteLine("SORT BY NLATEST");
}
}
我认为您对逐位操作知之甚少,因此我使用Enum.HasFlag
方法尽可能地简化了代码示例,该方法只检查给定的GetItemOptions
枚举已指定标志。
在使用RegexOptions Enumeration
或ControlStyles Enumeration
我建议你为每个参数创建一个enum
并定义一个这样的类:
public class PocketDataRequest
{
public State? State { get; set; }
public Favourite? Favourite { get; set; }
public ContentType? ContentType { get; set; }
public Sort? Sort { get; set; }
public DetailType? DetailType { get; set; }
public Dictionary<string, string> ToPostData()
{
return GetType().GetProperties()
.Where(p => p.GetValue(this, null) != null)
.ToDictionary(p => p.Name,
p => p.GetValue(this, null).ToString());
}
}
这将利用以下语法:
PocketDataRequest pocketDataRequest = new PocketDataRequest();
pocketDataRequest.State = State.Unread;
pocketDataRequest.Sort = Sort.Newest;
GetItemsBasedOn(pocketDataRequest.ToPostData());
在我的实现ToPostData
方法中,我使用LINQ和Reflection,这只是因为我很懒。您需要手动评估每个enum
值,尤其是当您要将enum
名称更改为更合适的名称时。此外,如果您尝试传递标题为favorite
的参数,我的代码将失败。这是因为favorite
取数字“0”或“1”。这不是一个大问题,因为你可以做的就像这样定义enum
:
public enum Favourite
{
UnfavouritedItems = 0,
FavouritedItems = 1
}
然后只需转换值(Int32)
并将该值添加到Dictionary<string, string>
或NameValueCollection
。