C#7:如何在泛型方法中使用元组(LINQ select 示例)
C#7: How to use tuples in generic methods (LINQ select example)
我有一些重复性很强的代码,它们始终具有相同的结构,只是使用数据库中的不同列来访问它并执行类似的操作
典型的查询如下所示:
var portfolioIds = context.PortSelMotorSeries
.Select(x => new { x.Id, x.InstallationAltitudeMax })
.ToList();
现在我想使用通用函数进行依赖倒置,并将选择器函数作为委托传递给查询:
private void ForEachIterate<T1>(Func<MotorSeriesDb, T1> selectorFunc): where T1 : (int Id, double Value)
{
...
var portfolioIds = context.PortSelMotorSeries
.Select(selectorFunct)
.ToList();
...
}
以便我可以使用自己的选择器调用查询:
ForEachIterate(x => new { Id = x.Id, Value = x.InstallationAltitudeMax });
ForEachIterate(x => new { Id = x.Id, Value = x.TemperatureMax });
使用“where T1 : (int Id, double Value)”指定约束会导致编译器错误 CS0701。
离开它会导致其他编译器错误。
有没有办法在泛型函数中使用元组?
如果您尝试这样做,它可能会起作用:
private static void ForEachIterate<T1>(Func<MotorSeriesDb, T1> selectorFunc) where T1 : Tuple<int, double>
{
var portfolioIds = context.PortSelMotorSeries
.Select(selectorFunct)
.ToList();
}
一方面,您将元组((int Id, double Value)
的东西)与匿名 类(new { Id = x.Id, Value = x.TemperatureMax }
的东西)混淆了。它们甚至不相关,因此您的代码永远不会按原样运行。
另一方面,如果你只想强制用户输出某种特定类型的元组,你可以这样做:
private void ForEachIterate(Func<MotorSeriesDb, (int, double)> selectorFunc)
{
...
var portfolioIds = context.PortSelMotorSeries
.Select(selectorFunct)
.ToList();
...
}
// call like:
ForEachIterate(x => (x.Id, x.InstallationAltitudeMax));
请注意,您的函数根本没有通用性。这引出了我的第三点:您错过了 Linq 的全部要点。你说的是控制反转,但你一开始就把它反转到了错误的方向。
您已经有了一个允许任意 selection 的结构:context.PortSelMotorSeries
。只需在调用站点中使用 Linq select 您想要的内容即可。
我有一些重复性很强的代码,它们始终具有相同的结构,只是使用数据库中的不同列来访问它并执行类似的操作
典型的查询如下所示:
var portfolioIds = context.PortSelMotorSeries
.Select(x => new { x.Id, x.InstallationAltitudeMax })
.ToList();
现在我想使用通用函数进行依赖倒置,并将选择器函数作为委托传递给查询:
private void ForEachIterate<T1>(Func<MotorSeriesDb, T1> selectorFunc): where T1 : (int Id, double Value)
{
...
var portfolioIds = context.PortSelMotorSeries
.Select(selectorFunct)
.ToList();
...
}
以便我可以使用自己的选择器调用查询:
ForEachIterate(x => new { Id = x.Id, Value = x.InstallationAltitudeMax });
ForEachIterate(x => new { Id = x.Id, Value = x.TemperatureMax });
使用“where T1 : (int Id, double Value)”指定约束会导致编译器错误 CS0701。
离开它会导致其他编译器错误。
有没有办法在泛型函数中使用元组?
如果您尝试这样做,它可能会起作用:
private static void ForEachIterate<T1>(Func<MotorSeriesDb, T1> selectorFunc) where T1 : Tuple<int, double>
{
var portfolioIds = context.PortSelMotorSeries
.Select(selectorFunct)
.ToList();
}
一方面,您将元组((int Id, double Value)
的东西)与匿名 类(new { Id = x.Id, Value = x.TemperatureMax }
的东西)混淆了。它们甚至不相关,因此您的代码永远不会按原样运行。
另一方面,如果你只想强制用户输出某种特定类型的元组,你可以这样做:
private void ForEachIterate(Func<MotorSeriesDb, (int, double)> selectorFunc)
{
...
var portfolioIds = context.PortSelMotorSeries
.Select(selectorFunct)
.ToList();
...
}
// call like:
ForEachIterate(x => (x.Id, x.InstallationAltitudeMax));
请注意,您的函数根本没有通用性。这引出了我的第三点:您错过了 Linq 的全部要点。你说的是控制反转,但你一开始就把它反转到了错误的方向。
您已经有了一个允许任意 selection 的结构:context.PortSelMotorSeries
。只需在调用站点中使用 Linq select 您想要的内容即可。