C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: ローカルメソッドに関する疑問


(過去ログ 141 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■82752 / inTopicNo.1)  ローカルメソッドに関する疑問
  
□投稿者/ Tomo (3回)-(2017/02/01(Wed) 16:08:58)

分類:[C#] 

ローカル関数はstaticメソッドやインスタンスメソッドと何が違うのか
いまいち理解できずに困っております。

ローカル関数はオブジェクトを生成する必要がないので
staticメソッドに近いものだとは思うのですが、いかんせんよくわかりません。

ローカルメソッドはstaticメソッドやインスタンスメソッドと
何が違うのか、教えていただけないでしょうか?
引用返信 編集キー/
■82753 / inTopicNo.2)  Re[1]: ローカルメソッドに関する疑問
□投稿者/ Hongliang (493回)-(2017/02/01(Wed) 16:23:20)
2017/02/01(Wed) 16:23:38 編集(投稿者)
まず、C#において、ローカル〜〜という名前のものは、一般に「メソッド類の内部で宣言されているもの」です。
void Test() {
    int a = 0; // aはローカル変数
}
なので、ローカル関数/ローカルメソッドというのは、メソッド内でさらに宣言されたメソッドと言うことになります。
void Test() {
    void Local() { }
}
が、少なくともVisual Studio 2015で標準で使えるC# 6までではこの機能は提供されていません。
// C# 7で追加予定だとか何とか。

さて、おっしゃっているのは多分こういうものではないと思います。
どういうものを指して「ローカル関数/ローカルメソッド」とおっしゃっていますか?
想定されているstaticメソッド、インスタンスメソッド、ローカルメソッドをそれぞれコードで示してみて下さい。

引用返信 編集キー/
■82755 / inTopicNo.3)  Re[1]: ローカルメソッドに関する疑問
□投稿者/ 魔界の仮面弁士 (1103回)-(2017/02/01(Wed) 16:55:24)
2017/02/01(Wed) 16:56:12 編集(投稿者)

No82752 (Tomo さん) に返信
> ローカル関数はstaticメソッドやインスタンスメソッドと何が違うのか
> いまいち理解できずに困っております。

「ローカル変数」「static変数」「インスタンス変数」の違いは分かりますか?
単純に言えば、それのメソッド版にあたるものです。


static メソッドやインスタンスメソッドは、クラスの直下にて定義されますが、
ローカル関数(local function)は、メソッドの中で定義されます。

ローカル変数が、定義したメソッドの中からしかアクセスできないのと同様、
ローカル関数も、定義したメソッドの中からしかアクセスできません。
(なお、ローカル関数の中にローカル関数を作ることも出来ます)


public static void Test1()  // 静的メソッド
{
  void Sample()  // ローカル関数
  {
  }

  Sample(); // ローカル関数の呼び出し
}

public static void Test2() // 静的メソッド
{
  //Sample();  // NG:Test1 内のローカル関数は Test1 からしか呼べない。
}


上記のような使いかたなら、匿名メソッドやラムダ式でも似たようなことはできます。

しかし、yield return を利用したり、型パラメーターを持ったジェネリックな定義にしたい場合は、
匿名メソッドやラムダ式だと対応できません。ローカル関数ならば大丈夫ですが。
引用返信 編集キー/
■82791 / inTopicNo.4)  Re[2]: ローカルメソッドに関する疑問
□投稿者/ Tomo (6回)-(2017/02/04(Sat) 21:41:26)
みなさん、すばやい回答ありがとうございます。
それから、申し訳ございません。

自分の知識不足から、質問の内容自体を間違えていました。

c#の匿名メソッドはローカルメソッドを作るものだと思い込んでいたんですが
匿名メソッドとローカルメソッドは別物でした。

それを踏まえて私が聞きたい事ですが、

匿名メソッドはスタティックメソッド、インスタンスメソッド
と何が違うのかを聞きたかったのです。

例えば、下記コードがあったとします。

delegate void CountIt(int end);

class Sample
{
static void Main()
{
CountIt count = delegate(int end)
{Console.Write(end);};
}
}

この場合、匿名メソッドを
戻り値なし、引数int のデリゲートに格納しています。

そして、次に下記コード

delegate void CountIt(int end);

class Sample
{
static void Main()
{
CountIt count = MethodA
}

static void MethodA(int end)
{
Console.Write(end);
}

}

この場合、静的メソッドを
戻り値なし、引数int のデリゲートに格納しています。

どちらの場合でも処理に問題はないので
匿名メソッドは名前のない静的メソッドと同じ扱い
と言って良いのだろうか?そう疑問に思っているのです

今回のコードの場合、匿名メソッドは名前のない静的メソッドである
そう言ってしまってよいのでしょうか?
その点をお聞きしたいのです。


引用返信 編集キー/
■82792 / inTopicNo.5)  Re[3]: ローカルメソッドに関する疑問
□投稿者/ Azulean (777回)-(2017/02/04(Sat) 23:06:01)
No82791 (Tomo さん) に返信
> 今回のコードの場合、匿名メソッドは名前のない静的メソッドである
> そう言ってしまってよいのでしょうか?
> その点をお聞きしたいのです。

最終的な性質は同じです。
コンパイラーが匿名メソッドを解釈し、自動的にスタティックメソッドやインスタンスメソッドを生成し、それを利用する形にしています。
このあたりの振る舞いは Visual Studio のインストール先の VC#\Specifications あたりにある文書の「匿名関数の変換」や「実装例」を参照すると良いでしょう。
引用返信 編集キー/
■82794 / inTopicNo.6)  Re[3]: ローカルメソッドに関する疑問
□投稿者/ 魔界の仮面弁士 (1110回)-(2017/02/05(Sun) 19:12:08)
No82791 (Tomo さん) に返信
> c#の匿名メソッドはローカルメソッドを作るものだと思い込んでいたんですが
> 匿名メソッドとローカルメソッドは別物でした。

蛇足ですが、C# の C は大文字で表記することになっていたりします。

ISO および JIS 規格において、「C#」の表記は
U+0043 (LATIN CAPITAL LETTER C) の後に
U+0023 (NUMBER SIGN #) と書くものと定められています。


> 匿名メソッドは名前のない静的メソッドと同じ扱い
> と言って良いのだろうか?そう疑問に思っているのです

メソッドに名前がない(実際にはコンパイル時に命名されますが)というだけですね。

デリゲートとして処理する場合に限って言えば、そのデリゲートインスタンスが
匿名メソッドなのかラムダ式なのか静的メソッドなのかインスタンスメソッドなのかは
特に区別する必要はないと思います。



class Sample
{
  public Action Method1 = delegate { Console.WriteLine("Anonymous"); };
  public Action Method2 = Sample.StaticMethod;
  public Action Method3;
  public static Action Method4 = delegate { Console.WriteLine("Anonymous"); };
  public static Action Method5 = Sample.StaticMethod;
  public static Action Method6;

  private static void StaticMethod() { Console.WriteLine("Static"); }
  private void InstanceMethod() { Console.WriteLine("Instance"); }
  public Sample() { this.Method3 = this.InstanceMethod; }
  static Sample() { Sample.Method6 = new Sample().InstanceMethod; }
}

class Program
{
  static void Main()
  {
    Console.WriteLine("デリゲートからの呼び出し");
    var sample = new Sample();
    sample.Method1();
    sample.Method2();
    sample.Method3();
    Sample.Method4();
    Sample.Method5();
    Sample.Method6();

    Console.WriteLine("デリゲートが参照しているメソッド");
    Console.WriteLine(sample.Method1.Method.Name);
    Console.WriteLine(sample.Method2.Method.Name);
    Console.WriteLine(sample.Method3.Method.Name);
    Console.WriteLine(Sample.Method4.Method.Name);
    Console.WriteLine(Sample.Method5.Method.Name);
    Console.WriteLine(Sample.Method6.Method.Name);
  }
}
引用返信 編集キー/
■82797 / inTopicNo.7)  Re[4]: ローカルメソッドに関する疑問
□投稿者/ Tomo (7回)-(2017/02/05(Sun) 20:25:16)
なるほど、とても分かりやすい回答ありがとうございます。
おかげさまで、匿名メソッドについて理解する事ができました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -