c# - C# - 接受任何类型的 IEnumerable 作为参数
问题描述
我有这个构造函数,它应该接受任何类型的任何 IEnumerable,并尝试将值转换为所需的类型
public ChartData(IEnumerable<dynamic> labels, IEnumerable<dynamic> values)
{
this.values = values.Select(x=>(float)Convert.ToString(x));
this.labels = labels.Select(x=>(string)Convert.ToString(x));
}
当我调用这个构造函数时,我可以传递字符串类型的 ienumerables,但不能传递 int 或 float 我如何创建一个可以接受任何类型的 ienumerables 而不会产生大量重载的构造函数?
解决方案
如果您接受任何类型,也包括IEnumerable<User>
and IEnumerable<Car>
,您希望如何将它们转换为浮点数和字符串?最好有一个封装浮点数和字符串值的对象,为此使用接口。例如,有一个这样的界面:
public interface IChartItem
{
float Value { get; set; }
string Label { get; set; }
}
一个示例类:
public class Foo : IChartItem
{
public int MyProperty { get; set; }
public string Name { get; set; }
public float Value => (float)MyProperty;
public string Label => Name;
}
现在您的函数可以是具有约束的通用函数:
public void ChartData<T>(IEnumerable<T> items)
where T : IChartItem
{
this.values = items.Select(x => x.Value);
this.labels = items.Select(x => x.Label);
}
替代选项
您还可以传入您的对象以及几个Func
参数来获取值和标签。例如:
public void ChartData<T>(IEnumerable<T> items,
Func<T, float> valueSelector,
Func<T, string> labelSelector)
{
this.values = items.Select(x => valueSelector(x));
this.labels = items.Select(x => labelSelector(x));
}
并像这样使用它:
ChartData(foos, f => (float)f.MyProperty, f => f.Name);