如何提取方法的参数名,并将它们用作Dictionary键
本文关键字:Dictionary 何提取 提取 参数 方法 | 更新日期: 2023-09-27 17:51:26
假设有这样一个简单的方法:
public async Task<ValidatePhoneNumberResult> ValidatePhoneNumberAsync(
string phone_number,
string country_code,
string country_iso,
DeviceUuid device_uuid, // DeviceUuid supports his own ToString();
string os_name,
string os_version,
string model,
string screen_resolution,
string sim_operator = "00000",
string is_usim = null
)
{
Uri uri = new Uri(MY_URI);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("phone_number", phone_number.ToString());
dic.Add("country_code", country_code.ToString());
dic.Add("country_iso", country_iso.ToString());
dic.Add("os_name", os_name.ToString());
dic.Add("model", model.ToString());
dic.Add("screen_resolution", screen_resolution.ToString());
dic.Add("sim_operator", sim_operator.ToString());
if (is_usim != null)
{
dic.Add("is_usim", is_usim.ToString());
}
request.Content = new FormUrlEncodedContent(dic);
return await GetResult<ValidatePhoneNumberResult>(request);
}
这是我的第一个设计。以后我会做很多这样的函数。但代码中有我不喜欢的东西。它是向字典中添加参数的一部分。我认为这是明显的代码重复。
- 所有参数名都用作字典的键。
- 它们都将实现自己的ToString()方法。
- 如果参数为
null
,则不应放入字典。
如果可以的话就更好了:
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("phone_number", phone_number.ToString());
dic.Add("country_code", country_code.ToString());
dic.Add("country_iso", country_iso.ToString());
dic.Add("os_name", os_name.ToString());
dic.Add("model", model.ToString());
dic.Add("screen_resolution", screen_resolution.ToString());
dic.Add("sim_operator", sim_operator.ToString());
if (is_usim != null)
{
dic.Add("is_usim", is_usim.ToString());
}
// To
var dic = ExtractParametersAndMakeItAsDictionary();
如何使用c#(5.0)语法编写此代码?如果你有更好的建议,我会很高兴听到的。如果不可能,是否可以用macro
包装它?(就像我们写C
时经常做的那样)告诉我任何可能的想法去重复代码:)
您可以尝试以下方法:
public void SomeMethod(string p1, int p2, object p3)
{
Dictionary<string, string> dic = ExtractParametersAndMakeItAsDictionary(p1, p2, p3);
}
private Dictionary<string, string> ExtractParametersAndMakeItAsDictionary(params object[] parameters)
{
StackTrace stackTrace = new StackTrace();
string methodName = stackTrace.GetFrame(1).GetMethod().Name;
ParameterInfo[] parameterInfos = GetType().GetMethod(methodName).GetParameters();
return parameters.Where(p => p != null).Zip(parameterInfos, (pv, pi) => new { Name = pi.Name, Value = pv.ToString() }).ToDictionary(x => x.Name, x => x.Value);
}
为什么不使用DTO呢?这将使序列化变得容易得多。
public static class Extensions
{
public static Dictionary<string, string> ToDicionary(this object o)
{
var dic = new Dictionary<string, string>();
foreach(var property in o.GetType().GetProperties())
{
dic.Add(property.Name, string.Format("{0}", property.GetValue(o)));
}
return dic;
}
}
如果你使用对象初始化语法,你甚至不需要改变调用它的方式:
public async Task<ValidatePhoneNumberResult> ValidatePhoneNumberAsync(object dto)
{
Uri uri = new Uri(MY_URI);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
request.Content = new FormUrlEncodedContent(dto.ToDictionary());
return await GetResult<ValidatePhoneNumberResult>(request);
}
你甚至不需要为它创建一个类型:
var result = await ValidatePhoneNumberAsync(
new
{
phone_number = "000000000",
country_code = "code",
country_iso = "iso",
device_uuid = new DeviceUuid(),
os_name = "Windows",
os_version = "6.3",
model = "model",
screen_resolution = "4K",
sim_operator = "00000",
is_usim = null
});