7

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));

しかし、それは醜いです。独自のスクロールバーが必要です!。私のVB.NETコードのように見えるC#で何かを書く方法はありますか?SinとCosのローカルラッパーメソッドを作成することはできますが、パフォーマンスが低下することはありませんか(関数呼び出しのオーバーヘッドのため)?そして、それには、私が使用しているすべてのクラスで使用しているすべての数学関数のラッパー関数を作成する必要があります。それもあまり望ましくありません。

4

7 に答える 7

12

System.Mathusingディレクティブを使用してエイリアスを指定できます。

using M = System.Math;

return new Vector3(M.Sin(az) * M.Cos(el), M.Cos(az) * M.Cos(el), M.Sin(el));

それは私が得た最高です。

SinとCosのローカルラッパーメソッドを作成することはできますが、パフォーマンスが低下することはありませんか(関数呼び出しのオーバーヘッドのため)?

その時点で、ジェネリックスやその他の機能を使用してさらに便利にすることができますが、このコードがメソッドとして発生している同じクラスですべての計算が行われていない限り、このようなライブラリを参照することになります。

「オーバーヘッドからのパフォーマンス」の質問は、「この単純なものの追加のスタックフレームは、標準のアプリケーションでは目立たない」で答えられます。あなたがタイトなループにいるなら、そうです、それは問題になるでしょう。

于 2012-06-19T19:07:59.597 に答える
9

using staticC#6.0以降では、宣言を追加することで数学参照を短縮できます。

using static System.Math;

Mathこれにより、タイプ名で修飾せずに、タイプの静的メンバーを使用できます。

public void Foo()
{
     var bar = Sin(8);
}

現在、using宣言をグローバルに適用する方法がまったくないため、これを「グローバルに」行う方法はありません。

C#6を使用していない場合

しかし、それはパフォーマンスを低下させませんか(関数呼び出しのオーバーヘッドのため)?

私はそれについて心配しません。最初に読めるようにコードを記述します。メソッドはいくつかの異なる方法で記述できます。1つ目は、空白を追加することです。

return new Vector3(
    Math.Sin(az) * Math.Cos(el),
    Math.Cos(az) * Math.Cos(el),
    Math.Sin(el)
);

それをヘルパーメソッドに入れることもできます。

jcolebrandの答えusing m = System.Math;はそれもいいことでしたが、どこにでも追加する必要があります。

于 2012-06-19T19:08:19.850 に答える
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で実際に使用される3つのパラメーターは何ですか?

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);

次の人が式が何であるかをよりよく理解するので、それは読みやすさを大いに改善するでしょう。

于 2012-06-19T19:09:31.247 に答える
7

しかし、それは醜いです。独自のスクロールバーが必要です!

はい、幅が短いStackOverflowでは可能です。代わりに、複数行に配置する必要があります。

return new Vector3(Math.Sin(az) * Math.Cos(el),
                   Math.Cos(az) * Math.Cos(el),
                   Math.Sin(el));

個人的には、とにかく読みやすくなっていると思います。これは、3つの異なる値がより明確に区別されているためです。空白行は、単なるコンマ、IMOよりも明確な区切り文字です。一緒に失われる可能性があるほど十分に類似しているいくつかの引数がある場合は、明確にするために複数の行を使用してください。

はい、いくつかの点で、などを書くことができればいいSin(az)のですが、C#にはそれを可能にするものがないので、代わりにコードを読みやすくするために再フォーマットすることに固執します。

于 2012-06-19T19:11:16.073 に答える
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());

コンパイラーは、パフォーマンスが実際に異ならないように、これらの呼び出しをインライン化する必要があります。

于 2012-06-19T19:12:39.177 に答える
1

拡張メソッドを使用することもできますが、結果はより不自然に見えます(余分な関数呼び出しが発生する可能性があり、インライン化される可能性もあります)。

static double Sin(this double value) { return Math.Sin(value);}

そして使用:

return new Vector3(az.Sin() * el.Cos(),....
于 2012-06-19T19:13:54.523 に答える
0

クラスだけでなく、C#のメソッドのエイリアスを定義することはできません。

于 2012-06-19T19:09:39.577 に答える