3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[C#] 拡張メソッドは、引数無しデリゲート型として関数に渡せない

Last updated at Posted at 2020-04-09

わかる人にとっては、当たり前といえば当たり前だが、
地味に時間を使ってしまったので、備忘録としてメモしておく。

static class TestExt
{
  public static bool IsTrue(this bool source) => source;
}
bool Func(Func<bool> func) => func();
bool IsTrue_Func() => true.IsTrue();

拡張メソッドは、ぱっと見、引数無しのデリゲート型(引数無しの関数)に見えるので、
以下のような呼び出しをしてしまったところ、コンパイルエラーとなった。
(拡張メソッドを引数無しの関数ポインタ的な取り扱いの感覚でコーディングしてしまった)

//Func(true.IsTrue);

よくよく考えれば、上記のような拡張メソッドは以下の関数と同等であると考えれば
エラーとなるのも納得できる。

//拡張メソッドは、以下と同等の為、引数無しデリゲート型として渡せないと思われる。
//Func(TestExt.IsTrue(true));

なので、下記の様にすれば問題はない。

//以下は可能
Func(() => true.IsTrue());
Func(IsTrue_Func);

追記:
また、紛らわしい内容だったかもしれないので捕捉しますと、
当然、以下の内容で回避できます。

@htsignさんのコメントより)

bool Func(Func<bool, bool> func) => func(true);

Func(TestExt.IsTrue);

が、以下の様には渡せません。

//Func(true.IsTrue);
//おそらく以下のように取り扱われているから?
//Func(TestExt.IsTrue(true));

元々、気軽に以下の様に渡そうとしていたので、
回避策はあるにせよ、もう少し上手くコンパイラが立ち回ってくれたらな
という身勝手な思いをつづってみた次第でございます。

//Func(true.IsTrue);
3
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?