ラベル C# の投稿を表示しています。 すべての投稿を表示
ラベル C# の投稿を表示しています。 すべての投稿を表示

public void なにか言う(string s, Action say) => say(s);
public void 言う(string s) => print(s);

public void ぴよって言う()=> なにか言う("ぴよ", 言う);

ぴよって言う()の中身の通り、なにか言う()は出力用の関数を外部からもらう形になっているので、言う()では無い関数を渡すことで、出力先や方法などを容易に変えることが出来ますの。(例えば、ファイルに出力するなど)

ちなみに、値を返さない関数の型はAction、返すものはFuncと書くそうですの。ここではActionを使う例のみ。

名前も微妙に長いしなぜわけたのですの。ぜんぶ、F<>でよかったような。

Actionの場合はまだいいけれど、Funcで「関数を返す関数」を返す、をやりはじめると定義が長くなりがちなので、なるべく短く書ける記法を用意しておいて欲しかったですの。

(あとで思ったけど、たしかにFuncだけだと値を返さない場合を表現しきれないので、わけるのはしょうがなかったのかもですの)

関数型発祥らしく、計算や判定の類は書きやすく、逆に、副作用が中心になる、手続き型を強制されるような部分は(単体では)書きにくいか書けないという感じだと思いますの。

基本的に大抵のことは出来て、別関数でお膳立てしてあげれば何でも出来る、という印象ですの。(お膳立てしすぎると、最悪、ラムダ式の部分がただのラッパーになるというのはあるにしろ、、)


また、C#7からは、式中で変数の宣言が出来るようになったそうで、逆に言えば、C#6ではそれが出来ないですの。

でも、単に変数を加工していく感じを真似るだけなら、selectでメソッドチェーンしていく構造にする手も。あまり意味はないかも知れないけれど。

例えば、引数で数値をもらって、それを要素1つのIEnumerableに変換してselectを繰り返して、最後に数値に戻して返す。

public int getPiyo(int x) => Enumerable.Repeat(x, 1).Select(c => c * 2).Select(c => c / 2).First();

意味があるかはともかく、一応出来るようですの。

ちなみに、この例のような数値計算なら
public int getPiyo(int x) => x * 2 / 2;
と書くのが圧倒的に素直ですの。

+ 日本語コーディングしようぜ
http://www.flat7th.org/~keizo/wiki/code2/KyDml6XmnKzoqp7jgrPjg7zjg4fjgqPjg7PjgrDjgZfjgojjgYbjgZw

日本語コーディング、そういうのもあるのかですの。

大会かなにかで賞金が成績によって決まるものがあったとして、
参加者が10人未満なら成績の合計、10人以上なら成績の平均の10倍が賞金になるとき、それを求めるクラスメソッド、

public int getBonus(IEnumerable scores)
{
 if (scores.Count() < 10)
 {
  return scores.Sum();
 }
 else
 {
  return (int)scores.Average() * 10;
 }
}

これを、ラムダ式と日本語コーディングにおまけで三項演算を加えて書くと以下ですの。

(一行版)
public int get賞金(IEnumerable 成績s) => 成績s.Count() < 10 ? 成績s.Sum() : (int)成績s.Average() * 10;

(改行を入れた版)
public int get賞金(IEnumerable 成績s) => 
成績s.Count() < 10
? 成績s.Sum()
: (int)成績s.Average() * 10;

量的に少ないせいか、思ったより迫力がないですの。むしろ最初のコードより短くて見やすい気もしますの。
ただ、わらわがC#の標準の中括弧の付け方(BSD/オールマン・スタイル)が嫌いなこともあって、そもそも中括弧を使わないで済むというのはとても爽快ですの。

使いそうなLinq関数

Select(式)(シーケンスを加工する)
Where(式)(条件を満たす要素を取得)
First()(先頭の要素を取得)
All(式)(すべての要素が条件を満たすか)
Any(式)(条件を満たす要素が1つでもあるか)
ToArray()(配列に変換)
Constains(値)(条件に一致する要素があるか)
ElementAt(値)(指定番目の要素を取得)

クラスメソッドとして書く場合は、
public int a(int n) => n + 1;
のような短文形式のみ可能で、
public int a(int n) => {(略); return n};
のようなブロックで囲う複文形式は許可されないですの。

同様に、if文は使えない…けれど、三項演算子は使えるようですの。
public int a(int n) => n == 1 ? 1 : 0;


式形式のメンバー (C# プログラミング ガイド)
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/statements-expressions-operators/expression-bodied-members
式本体の定義のサポートは、メソッドとプロパティの get アクセサーのために C# 6 で導入され、C# 7.0 で拡張されました。 
とあるように、基本的には簡単な(?)getアクセサ用にあるようですの。