カテゴリー
C

独習C#第3版、P557 式形式のラムダ

using System;

namespace Chapter01All
{
    delegate int Kasan(int x, int y);
    delegate int Genzan(int x, int y);
    class DeleGateSample
    {
 
        static void Main()
        {
            Kasan OpKasan = (x, y) => x + y;
            Genzan OpGenzan = (x, y) => x - y;
 
            Console.WriteLine(OpKasan(10, 20));
            Console.WriteLine(OpGenzan(10, 20));
            Console.WriteLine(OpKasan(100, 200));
            Console.WriteLine(OpGenzan(100, 200));
        }
    }
}

 デリゲートとともに式形式のラムダを使用する場合は、2つの手順が必要です。ひとつ目は使用するデリゲートの型を宣言することです。ふたつ目はそのデリゲート型の変数を宣言して、その変数にラムダ式を代入する。

カテゴリー
C

独習C#第3版、P469 課題12、13

using System;

namespace Util
{
    delegate void EventHandler(string str);
    class Sender
    {
        public event EventHandler Notify;
        public void Fire(string str)
        {
            if (Notify != null)
                Notify(str);
        }
    }
}
namespace Prog
{ 
    class Reciever
    {
        public void OnNotify(string str)
        {
            Console.WriteLine(str + "さん、called");
        }
    }
    class Kadai12syou
    {
        static void Main()
        {
            Util.Sender evt = new Util.Sender();
            evt.Notify += delegate (string str)
            {
                Console.WriteLine(str);            
            };
            evt.Fire("太郎");
            Reciever objR = new Reciever();
            evt.Notify += objR.OnNotify;
            evt.Fire("次郎");
        }
    }
}

delegate,eventはパターンが決まってるようなので、覚えておくしかないでしょう。問題の意味がつかめなかったのですが、大体は良かったかも。

カテゴリー
C

独習C#第3版、P454 イベントハンドラーに匿名メソッドを使う

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            SomeEvent(x); //←イベントを送信する
    }
}
class H2
{
    public void Handler2(int x)
    {
        Console.WriteLine("1から" + x + "迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa + "\n");
    }
}

class EventDemo
{
    static void Main()
    {
        H2 objH2 = new H2();
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        evt.SomeEvent += delegate(int x)
        {
            Console.WriteLine("1から" + x + "迄の和");
            int wa = 0;
            for (int i = 1; i <= x; i++)
                wa += i;
            Console.WriteLine(wa + "\n");

        };

        evt.SomeEvent += objH2.Handler2;

        // イベントを人為的に発生させる
        evt.Fire(20); //←イベントを発生させる

        evt.SomeEvent -= objH2.Handler2;
        evt.Fire(10);
    }
}

1からxまで集計する関数を匿名メソッドにしてみました。引数の例はなかったのですが、delegate(int x)でOKでした。2乗の集計は前のまま使います。イベントハンドラーのチェーンから匿名メソッドを削除う出来るか疑問ですが?

カテゴリー
C

独習C#第3版、P452 マルチキャストイベント

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            SomeEvent(x); //←イベントを送信する
    }
}

class EventDemo
{
    static void Handler(int x)
    {
        Console.WriteLine("1から10迄の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i;
        Console.WriteLine(wa);
       
    }
    static void Handler2(int x)
    {
        Console.WriteLine("1から10迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa);
       
    }

    static void Main()
    {
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += Handler2;

        // イベントを人為的に発生させる
        evt.Fire(10); //←イベントを発生させる
    }
}

HandlerとHandler2がMainと同じクラスclass EventDemoで、staticで構成されている。

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            SomeEvent(x); //←イベントを送信する
    }
}
class H1
{
    public void Handler(int x)
    {
        Console.WriteLine("1から" + x + "迄の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i;
        Console.WriteLine(wa);
    }
}
class H2
{
    public void Handler2(int x)
    {
        Console.WriteLine("1から" + x + "迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa);
    }
}

class EventDemo
{
    static void Main()
    {
        H1 objH1 = new H1();
        H2 objH2 = new H2();
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += objH1.Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += objH2.Handler2;

        // イベントを人為的に発生させる
        evt.Fire(20); //←イベントを発生させる
    }
}

HandlerとHandler2を別のクラスに分けて、インスタンスにHandlerを含ませてみました。

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            SomeEvent(x); //←イベントを送信する
    }
}
class H1
{
    public void Handler(int x)
    {
        Console.WriteLine("1から" + x + "迄の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i;
        Console.WriteLine(wa + "\n");
    }
}
class H2
{
    public void Handler2(int x)
    {
        Console.WriteLine("1から" + x + "迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa + "\n");
    }
}

class EventDemo
{
    static void Main()
    {
        H1 objH1 = new H1();
        H2 objH2 = new H2();
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += objH1.Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += objH2.Handler2;

        // イベントを人為的に発生させる
        evt.Fire(20); //←イベントを発生させる

        evt.SomeEvent -= objH1.Handler;
        evt.Fire(10);
    }
}

イベントチェーンから、objH1.Handlerを削除して、イベントを発生させてみました。

カテゴリー
C

独習C#第3版、P449 イベント

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            SomeEvent(x); //←イベントを送信する
    }
}

class EventDemo
{
    static void Handler(int x)
    {
        Console.WriteLine("1から10迄の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i;
        Console.WriteLine(wa);
    }
    static void Handler2(int x)
    {
        Console.WriteLine("1から10迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa);
    }

    static void Main()
    {
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += Handler2;

        // イベントを人為的に発生させる
        evt.Fire(10); //←イベントを発生させる
    }
}

上の例は下を変更しました。

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate void MyEventHandler(); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire()
    {
        if (SomeEvent != null)
            SomeEvent(); //←イベントを送信する
    }
}

class EventDemo
{
    static void Handler()
    {
        Console.WriteLine("1から10迄の和");
        int wa = 0;
        for (int i = 1; i <= 10; i++)
            wa += i;
        Console.WriteLine(wa);
    }
    static void Handler2()
    {
        Console.WriteLine("1から10迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= 10; i++)
            wa += i * i;
        Console.WriteLine(wa);
    }

    static void Main()
    {
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += Handler2;

        // イベントを人為的に発生させる
        evt.Fire(); //←イベントを発生させる
    }
}

こっちが最初です。

// とても簡単なイベントの例
 
using System;

// イベント用のデリゲートの宣言
delegate int MyEventHandler(int x); //←イベントで使うデリゲートを宣言する

// イベントの送信側のクラス
class MyEvent
{
    public event MyEventHandler SomeEvent; //←イベントを宣言する

    // イベント送信を実装したメソッド
    public void Fire(int x)
    {
        if (SomeEvent != null)
            Console.WriteLine(SomeEvent(x)); //←イベントを送信する
    }
}

class EventDemo
{
    static int Handler(int x)
    {
        Console.WriteLine("1から10迄の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i;
        Console.WriteLine(wa);
        return wa;
    }
    static int Handler2(int x)
    {
        Console.WriteLine("1から10迄の2乗の和");
        int wa = 0;
        for (int i = 1; i <= x; i++)
            wa += i * i;
        Console.WriteLine(wa);
        return wa;
    }

    static void Main()
    {
        MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する

        // ハンドラをイベントリストに追加する
        evt.SomeEvent += Handler; //←イベントのチェーンにハンドラを追加する
        evt.SomeEvent += Handler2;

        // イベントを人為的に発生させる
        evt.Fire(10); //←イベントを発生させる
    }
}

HandlerとHandler2をreturnする関数にしてみましたが、evt.Fire(10)ではHandler2のreturn値のみが帰っているようです。

カテゴリー
C

独習C#第3版、匿名メソッド

using System;

namespace Chapter01All
{
    class Ano
    {
        public int Syukei(int l)
        {
            int w = 0;
            for (int i = 1; i <= l; i++)
            {
                w += i;
            }
            return w;
        }
    }
    class Demo
    {
        static void Main()
        {
            Ano obj = new Ano();
            Console.WriteLine(obj.Syukei(10));
        }
    }
}

class AnoのインスタンスからSyukeiを呼ぶ場合。

using System;

namespace Chapter01All
{
    class Ano
    {
        public static int Syukei(int l)
        {
            int w = 0;
            for (int i = 1; i <= l; i++)
            {
                w += i;
            }
            return w;
        }
    }
    class Demo
    {
        static void Main()
        {
            //Ano obj = new Ano();
            Console.WriteLine(Ano.Syukei(10));
        }
    }
}

Syukeiをstatic に変えると、インスタンスでなくなるので、呼び出す方はAno.Syukei(10)とかになる。

using System;

namespace Chapter01All
{
    delegate int AnoSyukei(int limit);

    class Demo
    {
        static void Main()
        {
            AnoSyukei syukei = delegate (int limit)
            {
                int w = 0;
                for (int i = 1; i <= limit; i++)
                {
                    w += i;
                }
                return w;
            };
            Console.WriteLine(syukei(10));
        }
    }
}

 匿名メソッドに変えてみました。通常のメソッド呼び出し(つまり上の2例のように)の構文によってメソッドを呼び出すことが無い場合、使えるということです。

カテゴリー
C

独習C#第3版、P443 デリゲート、マルチキャスト

// マルチキャストのデモ

using System;
namespace Chapter01All
{
    // デリゲートの宣言
    delegate void StrMod(ref string str);

    class StringOps
    {
        // スペースをハイフンで置き換える
        public void ReplaceSpaces(ref string a)
        {
            Console.WriteLine("Replaces spaces with hyphens.");
            a = a.Replace(' ', '-');
        }
        public void ReplaceHyhoens(ref string a)
        {
            Console.WriteLine("Replaces hyphens with space");
            a = a.Replace('-', ' ');
        }

        // スペースを取り除く
        public void RemoveSpaces(ref string a)
        {
            string temp = "";
            int i;

            Console.WriteLine("Removing spaces.");
            for (i = 0; i < a.Length; i++)
                if (a[i] != ' ') temp += a[i];

            a = temp;
        }

        // 文字列の並びを逆転させる
        public void Reverse(ref string a)
        {
            string temp = "";
            int i, j;

            Console.WriteLine("Reversing string.");
            for (j = 0, i = a.Length - 1; i >= 0; i--, j++)
                temp += a[i];

            a = temp;
        }

        static void Main()
        {
            StringOps obj = new StringOps();
            // デリゲートの作成
            StrMod strOp;
            StrMod replaceSp = obj.ReplaceSpaces;
            StrMod removeSp = obj.RemoveSpaces;
            StrMod reverseStr = obj.Reverse;
            StrMod replacePyhoens = obj.ReplaceHyhoens;

            string str = "This is a test";
            strOp = replaceSp;
            strOp(ref str);
            Console.WriteLine(str + "\n");  //spを-に置き換える

//          strOp -= replaceSp;            
            strOp += reverseStr;
            strOp(ref str);
            Console.WriteLine(str + "\n");  //This-is-a-testを逆文字列にする

            strOp += replacePyhoens;        //再度逆文字列にするので元に戻る。-をspに変える。
            strOp(ref str);
            Console.WriteLine(str + "\n");
/*          以下のコメントアウトは最後以外は本の通りです。
            str = "This is a test.";
            strOp = replaceSp;
            strOp(ref str);
            Console.WriteLine(str + "\n");     //spを-に変える

            // マルチキャストの準備
            strOp = replaceSp;
            strOp += reverseStr; //←マルチキャストを作成する
            // マルチキャストの呼び出し
            str = "This is a test.";
            strOp(ref str);
            Console.WriteLine("Resulting string: " + str);
            Console.WriteLine();    //spaceを-に変えて、逆の文字列にする

            // 置き換えのメソッドを取り除き、スペース削除のメソッドを追加する
            str = "This is a test.";
            strOp = replaceSp;
            strOp += removeSp; //←別のマルチキャストを作成する
            strOp(ref str);
            Console.WriteLine(str + "\n");

            str = "This is a test."; // 文字列を再度設定する

            // マルチキャストの呼び出し
            strOp(ref str);         //文字列を逆にしてから、spを取る
            Console.WriteLine("Resulting string: " + str);
            Console.WriteLine();

            str = "This-is-a-test.";
            strOp = replacePyhoens;
            strOp(ref str);
            Console.WriteLine(str);
*/
        }
    }
}

 本の例題の通り、打ち込んでは見たけれど、少し分かり辛い。実行部分のコメントアウトは、大体本の通り。実行部分の最初を追加しました。例文のスペースをハイフンに変えて、文字列を逆にする。ハイフンをスペースに変えるのを追加して、再度文字列を逆にすると、元に戻る。マルチキャストは加えていくとそのまま残ってますので、スペースを置き換える手順等が残っていても、一度置き換えると、何度行っても何も起こらないことにはなるようです。文字列を逆にするのは、二回行うと元に戻ることになりますね。

カテゴリー
C

独習C#第3版、p439 簡単なデリゲートの例

using System;

namespace Chapter01All
{
    delegate string ProcName(string str);
    class DelegateStaticMethod
    {
        static string Reverse(string str)
        {
            string ans = "";
            for (int i = 0; i < str.Length; i++)
            {
                ans = str[i] + ans;
            }
            return ans;
        }

        static void Main()
        {
            ProcName instProc = Reverse;
            string str = "This is a test.";
            Console.WriteLine(instProc(str));
        }
    }    
}

もう一度復習の意味で、やって見ます。

using System;

namespace Chapter01All
{
    delegate string StrMod(string str);
    class StringOps  {
        public string Reverse(string str)
        {
            string ans = "";
            for (int i = 0; i < str.Length; i++)
            {
                ans = str[i] + ans;
            }
            return ans;
        }
    }

    class DelegateTest
    {
        static void Main()
        {
            StringOps so = new StringOps();
            string str;
            StrMod strOp = so.Reverse;
            str = strOp("This is a test.");
            Console.WriteLine(str);   
        }
    }
}

 前回はReverseはstaticでしたが、今回はメンバ関数の場合です。staticからpublicに変わってます。注意しないと変わったのを見落としそうになります。

カテゴリー
C

独習C#第3版、P489 ジェネリック型、コンストラクタ制約と継承を比較して見る

using System;

namespace Chapter01All
{
    class MyClass
    {
        public MyClass()
        {
            Console.WriteLine("Creaing a MyClass instance.");
        }
        public void SayHello()
        {
            Console.WriteLine("今日は");
        }
    }
    class Test : MyClass
    {      
        public Test()
        {
            Console.WriteLine("Creating a Test instance.");    
        }
        public void SayGoodBye()
        {
            SayHello();         //今日は
            Console.WriteLine("さようなら");
        }
    }
    class GenericConstractorDemo
    {
        static void Main()
        {
            Test t1 = new Test();
            t1.SayHello();      //今日は
            t1.SayGoodBye();            
        }
    }
}

using System;

namespace Chapter01All
{
    class MyClass
    {
        public MyClass()
        {
            Console.WriteLine("Creaing a MyClass instance.");
        }
        public void SayHello()
        {
            Console.WriteLine("今日は");
        }
    }
    class Test<T> where T : new()
    {
        T obj;
        public Test()
        {
            Console.WriteLine("Creating a Test instance.");
            obj = new T();
        }
        public void SayGoodBye()
        {
            Console.WriteLine("さようなら");
            //SayHelloを呼び出せない。継承であれば、出来た。
        }
    }
    class GenericConstractorDemo
    {
        static void Main()
        {
            Test<MyClass> t1 = new Test<MyClass>();
            t1.SayGoodBye();    //MyClassのSayHelloを呼び出せない。

            MyClass objA = new MyClass();
            objA.SayHello();    //MyClassのインスタンスは出来る。
        }
    }
}

MyClassのSayHelloを呼び出せるのか?出来ないのか?それだけではないと思いますが、違いが分からない。

カテゴリー
C

独習C#第3版、P485 型パラメータの制約、2つの型パラメータの関係を確立する制約

using System;

namespace Chapter01All
{

    class A
    {
        string str;
        public A(string a = "defalt Class A")
        {
            str = a;
        }
        public void OutMsgA()
        {
            Console.WriteLine(str);
        }
    }
    class B : A
    {
        string str;
        public B(string b)
        {
            str = b;
        }
        public void OutMsgB()
        {
            Console.WriteLine(str);
        }

    }
    class MyGenClass<T, V> where V : T
    {
        A objT;
        B objV;

        public void OutMsgAB(string ab)
        {
            objT = new A(ab);
            objT.OutMsgA();     //Class AB

            objV = new B(ab);
            objV.OutMsgB();     //Class AB
        }
    }

    class Demo
    {
        static void Main()
        {
            A objA = new A("Class A");
            objA.OutMsgA();     //Class A

            B objB = new B("Class B");
            objB.OutMsgA();     //Defalt Class A
            objB.OutMsgB();     //Class B

            MyGenClass<A, B> x = new MyGenClass<A, B>();
            x.OutMsgAB("Class AB");
        }
    }
}

 本の例も実行できない例です。それを実行できるようにしては見ましたが、必要性というか?意味がつかめてません。四苦八苦して見ました。

inserted by FC2 system