我有这样一种方法:
internal PointGeospatial ConvertToSpherical(double x, double y, double z)
我想知道,确实存在这样一种可能性来处理C#中某些函数式方法中的所有参数,如(伪代码):
ConvertToSpherical(double x, double y, double z) ::(x) -> arg->Rad2Deg(x)
这是一个伪代码,但根据这个想法,我认为你得到了我想要的东西。当然有一种制作子方法的方法,比如PrepareCoordinates(x, y, z)
,foreach
我会准备3个变量并发送到ConvertToSpherical()
,但这太必要了。
我想要一些很酷的lamda(类似功能语言)风格。我可以在C#中提问吗?
答案 0 :(得分:0)
很抱歉急于阅读问题。这是一个想法,使用IEnumerables
作为向量:
Func<IEnumerable<double>, IEnumerable<double>> convertToSpherical = a => a.Select(Rad2Deg);
var list = new[] {0, Math.PI, Math.PI*2};
var newList = convertToSpherical(list);
foreach (var i in newList)
{
Console.WriteLine(i);
}
其中:
private static double Rad2Deg(double radians)
{
return radians*180/Math.PI;
}
我发现拥有x
,y
,z
变量是一种痛苦,并且无论如何都容易出现复制粘贴错误,因此总是会建议array
s / {{ 1}}向量。
答案 1 :(得分:0)
我对您的问题的理解是,您希望使用Rad2Deg
方法将每个参数投影到新值,其签名和返回类型类似于Func<double, double>
。
我没有看到任何特别好的方式。最好的是perharps:
internal PointGeospatial ConvertToSpherical(double x, double y, double z)
{
var changedArgs = new[] { x, y, z, }.Select(Rad2Deg).ToArray();
// rest of method
}
但它不会更改原始变量,因此您可能会偶然使用x
,y
和z
。
如果您更改了方法的签名以获取数组(使用params
,那么您仍然可以使用相同的调用语法调用它),您可以这样做:
internal PointGeospatial ConvertToSpherical(params double[] x)
{
for (int i = 0; i < x.Length; ++i)
x[i] = Rad2Deg(x[i]);
// rest of method
}
我也可以用箭头做最后一个案例,但它有点难看。你需要这个:
namespace N
{
delegate void ActionWithRef<T>(ref T obj);
static class MyExtensions
{
public static void ForEachWithRef<T>(this T[] array, ActionWithRef<T> action)
{
for (int i = 0; i < array.Length; ++i)
action(ref array[i]);
}
}
}
然后你可以这样做:
// ugly?
// included in this post because it looks a bit like the pseudocode of your question
internal PointGeospatial ConvertToSpherical(params double[] x)
{
x.ForEachWithRef((ref double t) => t = Rad2Deg(t));
// rest of method
}
或许有点不那么难看:
namespace N
{
static class MyExtensions
{
public static void MutateAll<T>(this T[] array, Func<T, T> selector)
{
for (int i = 0; i < array.Length; ++i)
array[i] = selector(array[i]);
}
}
}
并使用:
internal PointGeospatial ConvertToSpherical(params double[] x)
{
x.MutateAll(Rad2Deg);
// rest of method
}
当你只有三个参数时,我不会说我实际推荐任何这些“解决方案”,但它会显示你在C#中可以做什么(而且不能做)。
在我使用params
的所有情况下,如果ConvertToSpherical
的调用者选择以未展开的形式调用该方法,并且如果他保留对他通过的double[]
实例的引用,然后他会发现当方法返回时,他的数组内容已经改变了。
同样使用params
示例,当然不会在编译时检查传递了多少个参数(正好是三个或不是)。
这是重复的,非功能性的解决方案:
internal PointGeospatial ConvertToSpherical(double x, double y, double z)
{
x = Rad2Deg(x);
y = Rad2Deg(y);
z = Rad2Deg(z);
// rest of method
}
- )