在VB.NET中,通过导入System.Math并直接引用其方法,我可以使我的数学代码更加清晰:
Imports System.Math
[...]
Return New Vector3(Sin(az) * Cos(el), Cos(az) * Cos(el), Sin(el))
但是我不认为C#可以使用类来隐式访问它们的方法,所以我必须做类似的事情:
using System;
[...]
return new Vector3(Math.Sin(az) * Math.Cos(el), Math.Cos(az) * Math.Cos(el), Math.Sin(el));
但那很难看;它需要自己的滚动条!有没有办法用C#写一些看起来像我的VB.NET代码的东西?我可以为Sin和Cos编写局部包装器方法,但不会降低性能(因为函数调用的开销)?而且,这需要为我正在使用的每个类中使用的每个Math函数编写包装函数;这也不是那么令人满意。
答案 0 :(得分:12)
您可以使用using指令为System.Math
添加别名:
using M = System.Math;
return new Vector3(M.Sin(az) * M.Cos(el), M.Cos(az) * M.Cos(el), M.Sin(el));
这是我得到的最好的。
我可以为Sin和Cos编写局部包装器方法,但这不会降低性能(因为函数调用的开销)?
你可以,并且在那时你可以使用泛型和其他细节来使它更方便,但你仍然会引用这样的库,除非所有数学都发生在发生此代码的同一个类中作为方法。
“从开销中获得性能”这一问题的答案是“额外的堆栈帧,这对于标准应用程序而言非常明显。”如果你处于紧张的循环中,那么是的,这将是一个问题。
答案 1 :(得分:9)
从C#6.0开始,您可以通过添加using static
声明缩短数学参考:
using static System.Math;
这允许您使用Math
类型的静态成员,而不使用类型名称限定它:
public void Foo()
{
var bar = Sin(8);
}
由于目前根本无法在全球范围内应用使用声明,因此无法“全局”执行此操作。
对于那些不使用C#6的人
但不会降低性能(因为函数调用的开销)?
我不担心。首先将代码编写为可读。我们可以用几种不同的方式编写方法。第一个是添加空格:
return new Vector3(
Math.Sin(az) * Math.Cos(el),
Math.Cos(az) * Math.Cos(el),
Math.Sin(el)
);
您也可以将它放在辅助方法中。
jcolebrand's answer这样做很不错,但它需要在任何地方添加using m = System.Math;
。
答案 2 :(得分:7)
您可以添加
using M = System.Math;
然后再做
return new Vector3(M.Sin(az) * M.Cos(el), M.Cos(az) * M.Cos(el), M.Sin(el));
但....我没有看到真正的价值
事实上,我认为应该存储每个变量,并用更好的名称来表示它们是什么。看着这个,我看不出正在做什么。
var sinAz = Math.Sin(az); //Could these be named better? Perhaps with words in the correct domain
var cosAz = Math.Cos(az);
var sinEl = Math.Sin(el);
var cosEl = Math.Cos(el);
return new Vector3(sinAz * cosEl, cosAz * cosEl, sinEl);
或者更好的是,Vector3实际使用的三个参数是什么?
var parm1 = Math.Sin(Az) * Math.Cos(El); //What should parm1, parm2, parm3 be called?
var parm2 = Math.Cos(Az) * Math.Cos(El);
var parm3 = Math.Sin(Az);
return new Vector3(parm1, parm2, parm3);
这将极大地提高可读性,因为下一个人可以更好地理解公式是什么。
答案 3 :(得分:7)
但那很难看;它需要自己的滚动条!
是,在Stack Overflow上,宽度很短。你必须把它放在多行上:
return new Vector3(Math.Sin(az) * Math.Cos(el),
Math.Cos(az) * Math.Cos(el),
Math.Sin(el));
就我个人而言,我认为更具可读性,因为现在三个不同的值更加清晰。空白行是一个比逗号,IMO更清晰的分隔符。如果你有几个足够相似的参数可以一起丢失,那么为了清晰起见,请使用多行。
是的,如果你能写Sin(az)
等,它会在某些方面很好 - 但C#中没有任何内容可以让你这样做,所以我坚持重新格式化相反,可读性代码。
答案 4 :(得分:5)
您可以创建一个将调用包装为扩展方法的类:
public static class MathExtensions {
public static double Sin(this double value) {
return Math.Sin(value);
}
public static double Cos(this double value) {
return Math.Cos(value);
}
}
return new Vector3(az.Sin() * el.Cos(), az.Cos() * el.Cos(), el.Sin());
编译器应该内联这些调用,以便性能不应该真正区别。
答案 5 :(得分:1)
您也可以使用扩展方法,但结果看起来会更不自然(可能有额外的函数调用,也可能会被内联):
static double Sin(this double value) { return Math.Sin(value);}
并使用:
return new Vector3(az.Sin() * el.Cos(),....
答案 6 :(得分:0)
您无法在C#中定义方法的别名,只能在类中定义。