c# - 使用泛型将带有字符串键的字典转换为带有枚举键的字典
问题描述
我有一堆从外部来源读取的字典(以字符串为键)。我想将所有字典转换为具有不同枚举作为键的字典。对于每个枚举,我都有一个将字符串转换为枚举的自定义方法。
与其为每种枚举类型编写一个转换函数,我希望我可以为所有类型编写一个通用方法。
我不太熟悉泛型(或类型检查),但下面的代码是编写函数的尝试。vs-intellisense 不喜欢这种解决方案。有可能做我想做的事吗?如果是这样,怎么办?
我使用 .Net Framework 4.5.2,所以我猜那是 C# 5.0(并且更新目前不是一个选项)。
public enum Product { Product1, Product2, Product3 };
public enum Fund { Fund1, Fund2, Fund3 }
//...and lots of different enums
private static Dictionary<T, double> ConvertDict<T>(Dictionary<string, double> dict) where T : Enum
{
var returnDict = new Dictionary<T, double>();
//Here ideally I would do something like this
switch (typeof(T))
{
case typeof(Product): //This a no go
foreach (var keyValuePar in dict)
returnDict.Add(CustomProductEnumConverter(keyValuePar.Key), keyValuePar.Value);
break;
case typeof(Fund): //This a no go
foreach (var keyValuePar in dict)
returnDict.Add(CustomFundEnumConverter(keyValuePar.Key), keyValuePar.Value);
break;
default:
throw new Exception("Unknown enum-type");
}
return returnDict;
}
public static Product CustomProductEnumConverter(string productName)
{
//No clear link between enum name and string value...
if (productName == "base012")
return Product.Coffee;
if (productName == "defa341")
return Product.Milk;
if (productName == "urak451")
return Product.Juice;
//...
}
这个想法是我可以像这样调用我的新函数
var prodDictA = ConvertToDict<Product>(rawProdDictA)
var prodDictB = ConvertToDict<Product>(rawProdDictB)
var fundDictA = ConvertToDict<Fund>(rawFundDictA)
//etc...
解决方案
您可以通过为密钥注入转换器来解决它;从string
到想要的密钥类型T
。
这是一个例子:
public enum Product { Product1, Product2, Product3 };
public enum Fund { Fund1, Fund2, Fund3 }
//...and lots of different enums
private static Dictionary<T, double> ConvertDict<T>(
Dictionary<string, double> dict,
Func<string, T> convertKey)
{
var returnDict = new Dictionary<T, double>();
foreach (var kvp in dict)
{
returnDict.Add(convertKey(kvp.Key), kvp.Value);
}
return returnDict;
}
private static Product ConvertProductName(string productName)
{
if (productName == "prod1")
return Product.Product1;
if (productName == "prod2")
return Product.Product2;
if (productName == "prod3")
return Product.Product3;
throw new ArgumentException("Unknown product: " + productName);
}
private static Fund ConvertFundName(string fundName)
{
if (fundName == "fund1")
return Fund.Fund1;
if (fundName == "fund2")
return Fund.Fund2;
if (fundName == "fund3")
return Fund.Fund3;
throw new ArgumentException("Unknown fund: " + fundName);
}
简化:ConvertDict
可以使用单个 LINQ 表达式重写该方法,如下所示:
private static Dictionary<T, double> ConvertDict<T>(
Dictionary<string, double> dict,
Func<string, T> convertKey)
{
return dict.ToDictionary(
kvp => convertKey(kvp.Key),
kvp => kvp.Value);
}
简化:switch
使用语句转换方法会更好:
private static Product ConvertProductName(string productName)
{
switch (productName)
{
case "prod1": return Product.Product1;
case "prod2": return Product.Product2;
case "prod3": return Product.Product3;
default:
throw new ArgumentException("Unknown product: " + productName);
}
}
然后你这样称呼它:
Dictionary<Product, double> prodDictA = ConvertDict<Product>(rawProdDictA, ConvertProductName);
Dictionary<Product, double> prodDictB = ConvertDict<Product>(rawProdDictB, ConvertProductName);
Dictionary<Fund, double> fundDictA = ConvertDict<Fund>(rawFundDictA, ConvertFundName);
简化:或者,您甚至可以省略泛型类型,让编译器找出<T>
您使用的给定 convertKey 函数:
Dictionary<Product, double> prodDictA = ConvertDict(rawProdDictA, ConvertProductName);
Dictionary<Product, double> prodDictB = ConvertDict(rawProdDictB, ConvertProductName);
Dictionary<Fund, double> fundDictA = ConvertDict(rawFundDictA, ConvertFundName);
推荐阅读
- c++ - C++ 我试图结束这个无限循环以找到 0 和用户输入值之间的偶数
- csv - Jitterbit:虽然选中了“不创建 emtpy 文件”,但仅使用标题创建目标 CSV 文件
- python - Mac pip install pyodbc 失败,找不到 -lodbc 的库
- uwp - PointerReleased 在 UWP 控制之外不起作用
- r - ggplot:直方图中的 xlim 和 scale_x_continuous
- c++ - 如何向量::emplace_back 具有shared_mutex 的类?
- python-3.x - 在python中将变量添加到列表中
- c# - Blazor Blazored.LocalStorage.ILocalStorageService 任务取消
- javascript - 关于在另一个函数中调用异步函数的问题
- java - 在java中将非整数天转换为实际日期?