0

私はそのような方法を持っています:

internal PointGeospatial ConvertToSpherical(double x, double y, double z)

(疑似コード)のように、C#の関数スタイルでメソッド内のすべての引数を処理する可能性があるのだろうか:

ConvertToSpherical(double x, double y, double z) ::(x) -> arg->Rad2Deg(x)

これは疑似コードですが、アイデアによって、私が望むものが得られると思います。もちろん、 3 つの変数を準備して に送信するPrepareCoordinates(x, y, z)場所のように、サブメソッドを作成する方法もありますが、それはあまりにも必須です。foreachConvertToSpherical()

クールなラムダのような (関数型言語のような) スタイルが欲しいです。私の質問でC#で可能ですか?

4

2 に答える 2

0

あなたの質問に対する私の理解は、Rad2Deg署名と戻り値の型がFunc<double, double>.

私はそれを行うのに特に良い方法は見当たりません。最高のものはおそらく次のとおりです。

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
}

パラメーターが 3 つしかない場合にこれらの「ソリューション」を実際に推奨するとは言いませんが、C# でできること (およびできないこと) を示しています。

私が を使用するすべての場合paramsにおいて、 の呼び出し元ConvertToSphericalが展開されていない形式でメソッドを呼び出すことを選択し、double[]渡したインスタンスへの参照を保持している場合、メソッドが戻ったときに配列の内容が変更されていることに気付くでしょう。

また、params例では、もちろん、渡される引数の数 (正確に 3 つかどうか) はコンパイル時にチェックされません。

反復的で機能しないソリューションは次のとおりです。

internal PointGeospatial ConvertToSpherical(double x, double y, double z)
{
  x = Rad2Deg(x);
  y = Rad2Deg(y);
  z = Rad2Deg(z);

  // rest of method
}

;-)

于 2013-10-11T09:40:37.300 に答える
0

急いで Q を読んで申し訳ありません。IEnumerablesベクトルとして使用する 1 つのアイデアを次に示します。

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は苦痛であり、とにかくコピーアンドペースト エラーが発生しやすいため、常にarrays/IEnumerableベクトルをお勧めします。

于 2013-10-11T09:19:18.313 に答える