none
処理や別のオブジェクトを変数へ入れる方法 RRS feed

  • 質問

  • C#について質問です。

    例えば、次のような文があったとします。

    hoge1.Show();

    この時、「 hoge1」をhogeと1という文字を連結して、hogesという変数に入れて

    hoges.Show();

    のように実行することは可能なのでしょうか。
    目的としては、以上のように連番の値を変えたかったり、Showの部分を別のメソッドとして実行したいのです。

    ご回答、お願い致します。


    2017年1月19日 6:45

回答

  • 以下のようなことでしょうか?

    文字列で指定されたクラスのインスタンスを作成し、メソッドを実行する
    http://dobon.net/vb/dotnet/programing/createinstancefromstring.html


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    2017年1月19日 7:04
    モデレータ
  • こういうことをやりたいのだろうか

    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Hoge hoge1 = new Hoge(1);
                Hoge hoge2 = new Hoge(2);
                Hoge hoge3 = new Hoge(3);
                Fuga fuga1 = new Fuga(1);
                Fuga fuga2 = new Fuga(2);
    
                Console.WriteLine("***********************");
    
                Named<Hoge> hoges = new Named<Hoge>();//Hoge型を名前を付けて登録できるようにする
                hoges.Add("hoge1", hoge1);
                hoges.Add("hoge2", hoge1);
    
                hoges.TargetName = "hoge" + "1";
                hoges.Target.Show();//対象のShowメソッドを呼ぶ
    
                Console.WriteLine("***********************");
    
                Named<Fuga> fugas = new Named<Fuga>();//Fuga型を名前を付けて登録できるようにする
                fugas.Add("fuga1", fuga1);
                fugas.Add("fuga2", fuga1);
    
    
                fugas.TargetName = "fuga" + "1";
                fugas.Target.Flash();
    
                Console.WriteLine("***********************");
    
                Named<Action> actions = new Named<Action>(); //Actionデリゲートでメソッドに名前を付けて登録できるようにする
                actions.Add("hoge1", hoge1.Show); //Show()は引数無しなのでActionデリゲートにできる
                actions.Add("hoge2", hoge2.Hide); //Hide()も引数無しなのでActionデリゲートにできる
                actions.Add("fuga1", fuga1.Flash);
                actions.Add("fuga2", () => { fuga2.Blink("☆"); }); //Blink()は引数無しなので直接呼べないのでラムダ式で引数なしデリゲートをつくる
    
                actions.TargetName = "hoge" + "2";
                actions.Target();//対象になっているActionを実行する
    
                actions.TargetName = "fuga" + "1";
                actions.Target();
    
                actions.TargetName = "fuga" + "2";
                actions.Target();
    
                Console.WriteLine("***********************");
                Named<Action<string>> functions = new Named<Action<string>>(); //引数ありのメソッドも同様に
                functions.Add("hoge1", hoge1.Close);
                functions.Add("fuga1", fuga1.Blink);
                //functions.Add(nameof(fuga2), fuga2.Blink); //VS2015以降ならnameofで変数名参照できます
    
                functions.TargetName = "hoge" + "1";
                functions.Target("★");
            }
        }
    
        class Named<T>
        {
            private readonly Dictionary<string, T> Items = new Dictionary<string, T>();//文字列をキーにして特定型を保存できる辞書
            public void Add(string name, T item)
            {
                Items.Add(name, item);
            }
            public string TargetName { get; set; }
            public T Target
            {
                get
                {
                    return Items[TargetName];//TargetNameをキーにして操作対象を取り出す
                }
            }
        }
    
        class Hoge
        {
            public Hoge(int num)
            {
                this.number = num;
            }
            private int number;
            public void Show() { Console.WriteLine("Hoge Show " + number); }
            public void Hide() { Console.WriteLine("Hoge Hide " + number); }
            public void Close(string value) { Console.WriteLine("Hoge Close " + number + value); }
        }
        class Fuga
        {
            public Fuga(int num)
            {
                this.number = num;
            }
            private int number;
            public void Flash() { Console.WriteLine("Fuga Flash " + number); }
            public void Blink(string arg) { Console.WriteLine("Fuga Blink " + number + arg); }
        }
    }

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2017年1月19日 9:24
  • 変数名そのものは、実行時には消えています。
    デバッグ時に変数名がわかるのは、別のところに変数名と、その変数名で記録したいものを入れているアドレスが記録されているからです。

    「hoge」という名前にしろ、「~の1番目」という意味にしろ、人間にとっては意味を持ちますが、コンピュータには意味を持ちません。おそらく、hogeN (N は任意の自然数)という「変数」が用意してあり、それを順番に切り替えて使いたいということだと思います。

    一番簡単な方法は、配列に入れることです。
    Control[] hoges = new Control[] { hoge1, hoge2, hoge3, ... };
    hoges[N - 1].Show();  // 0 始まりなので 1 引くか、添え字 0 を null にするか。

    質問されていることに近いのは、連想配列を使うことです。
    Dictionary<string, Control> hoges = new Dictionary<string, Control> {
    { "hoge1", hoge1 }, { "hoge2", hoge2 }, { "hoge3", hoge3 }, ... };
    hoges["hoge2"].Show();

    また、ウィンドウに表示しているコントロールなら、Name プロパティに名前を持っているので、それで検索することができます。

    まぁ、なんにしても、文脈の途中だけを取り出して質問されても、わかりにくいやね。


    Jitta@わんくま同盟

    2017年1月21日 3:57

すべての返信

  • 以下のようなことでしょうか?

    文字列で指定されたクラスのインスタンスを作成し、メソッドを実行する
    http://dobon.net/vb/dotnet/programing/createinstancefromstring.html


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    2017年1月19日 7:04
    モデレータ
  • こういうことをやりたいのだろうか

    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Hoge hoge1 = new Hoge(1);
                Hoge hoge2 = new Hoge(2);
                Hoge hoge3 = new Hoge(3);
                Fuga fuga1 = new Fuga(1);
                Fuga fuga2 = new Fuga(2);
    
                Console.WriteLine("***********************");
    
                Named<Hoge> hoges = new Named<Hoge>();//Hoge型を名前を付けて登録できるようにする
                hoges.Add("hoge1", hoge1);
                hoges.Add("hoge2", hoge1);
    
                hoges.TargetName = "hoge" + "1";
                hoges.Target.Show();//対象のShowメソッドを呼ぶ
    
                Console.WriteLine("***********************");
    
                Named<Fuga> fugas = new Named<Fuga>();//Fuga型を名前を付けて登録できるようにする
                fugas.Add("fuga1", fuga1);
                fugas.Add("fuga2", fuga1);
    
    
                fugas.TargetName = "fuga" + "1";
                fugas.Target.Flash();
    
                Console.WriteLine("***********************");
    
                Named<Action> actions = new Named<Action>(); //Actionデリゲートでメソッドに名前を付けて登録できるようにする
                actions.Add("hoge1", hoge1.Show); //Show()は引数無しなのでActionデリゲートにできる
                actions.Add("hoge2", hoge2.Hide); //Hide()も引数無しなのでActionデリゲートにできる
                actions.Add("fuga1", fuga1.Flash);
                actions.Add("fuga2", () => { fuga2.Blink("☆"); }); //Blink()は引数無しなので直接呼べないのでラムダ式で引数なしデリゲートをつくる
    
                actions.TargetName = "hoge" + "2";
                actions.Target();//対象になっているActionを実行する
    
                actions.TargetName = "fuga" + "1";
                actions.Target();
    
                actions.TargetName = "fuga" + "2";
                actions.Target();
    
                Console.WriteLine("***********************");
                Named<Action<string>> functions = new Named<Action<string>>(); //引数ありのメソッドも同様に
                functions.Add("hoge1", hoge1.Close);
                functions.Add("fuga1", fuga1.Blink);
                //functions.Add(nameof(fuga2), fuga2.Blink); //VS2015以降ならnameofで変数名参照できます
    
                functions.TargetName = "hoge" + "1";
                functions.Target("★");
            }
        }
    
        class Named<T>
        {
            private readonly Dictionary<string, T> Items = new Dictionary<string, T>();//文字列をキーにして特定型を保存できる辞書
            public void Add(string name, T item)
            {
                Items.Add(name, item);
            }
            public string TargetName { get; set; }
            public T Target
            {
                get
                {
                    return Items[TargetName];//TargetNameをキーにして操作対象を取り出す
                }
            }
        }
    
        class Hoge
        {
            public Hoge(int num)
            {
                this.number = num;
            }
            private int number;
            public void Show() { Console.WriteLine("Hoge Show " + number); }
            public void Hide() { Console.WriteLine("Hoge Hide " + number); }
            public void Close(string value) { Console.WriteLine("Hoge Close " + number + value); }
        }
        class Fuga
        {
            public Fuga(int num)
            {
                this.number = num;
            }
            private int number;
            public void Flash() { Console.WriteLine("Fuga Flash " + number); }
            public void Blink(string arg) { Console.WriteLine("Fuga Blink " + number + arg); }
        }
    }

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2017年1月19日 9:24
  • フォーラム オペレーターの栗下 望です。
    Takuma.N さん、ご投稿いただきありがとうございます。

    ご質問いただきました内容につきましては、
    「.NET Framework」カテゴリのほうが情報が集まりやすいと思われるため、
    移動させていただきました。

     >.NET Framework

    ご自身のスレッドは、「クイックアクセス」の「マイスレッド」の一覧で確認することが出来ます。

    フォーラム ユーザーからの回答がお役にたちましたら、投稿者からの[回答としてマーク] をお願いいたします。

    どうぞよろしくお願いいたします。


    MSDN/TechNet Community Support 栗下 望

    2017年1月20日 2:56
    モデレータ
  • 変数名そのものは、実行時には消えています。
    デバッグ時に変数名がわかるのは、別のところに変数名と、その変数名で記録したいものを入れているアドレスが記録されているからです。

    「hoge」という名前にしろ、「~の1番目」という意味にしろ、人間にとっては意味を持ちますが、コンピュータには意味を持ちません。おそらく、hogeN (N は任意の自然数)という「変数」が用意してあり、それを順番に切り替えて使いたいということだと思います。

    一番簡単な方法は、配列に入れることです。
    Control[] hoges = new Control[] { hoge1, hoge2, hoge3, ... };
    hoges[N - 1].Show();  // 0 始まりなので 1 引くか、添え字 0 を null にするか。

    質問されていることに近いのは、連想配列を使うことです。
    Dictionary<string, Control> hoges = new Dictionary<string, Control> {
    { "hoge1", hoge1 }, { "hoge2", hoge2 }, { "hoge3", hoge3 }, ... };
    hoges["hoge2"].Show();

    また、ウィンドウに表示しているコントロールなら、Name プロパティに名前を持っているので、それで検索することができます。

    まぁ、なんにしても、文脈の途中だけを取り出して質問されても、わかりにくいやね。


    Jitta@わんくま同盟

    2017年1月21日 3:57