カテゴリー
C

独習C#第3版、P456 名前空間の例

using System;

namespace NMSSisokuenzan
{
    class SisokuEnzan
    {
        int firstNumber;
        int secondNumber;
        int wa;
        int sa;
        int seki;
        double waru;
        public SisokuEnzan(int x, int y)
        {
            firstNumber = x;
            secondNumber = y;
        }
        public void Kasan()
        {
            wa = firstNumber + secondNumber;
        }
        public void Genzan()
        {
            sa = firstNumber - secondNumber;
        }
        public void Kakezan()
        {
            seki = firstNumber * secondNumber;
        }
        public void Warizan()
        {
            waru = (double)firstNumber / secondNumber;
        }
        public int PKasan
        {
            get
            {
                return wa;
            }
        }
        public int PGenzan
        {
            get
            {
                return sa;
            }
        }
        public int PKakezan
        {
            get
            {
                return seki;
            }
        }

        public double PWarizan
        {
            get
            {
                return waru;
            }
        }
    }
}
namespace SisokuEnzanDemo
{ 
    class EnzanDemo
    {
        static void Main()
        {
            NMSSisokuenzan.SisokuEnzan obj = new NMSSisokuenzan.SisokuEnzan(100, 200);
            obj.Kasan(); obj.Genzan(); obj.Kakezan(); obj.Warizan();
            Console.WriteLine(obj.PKasan);
            Console.WriteLine(obj.PGenzan);
            Console.WriteLine(obj.PKakezan);
            Console.WriteLine(obj.PWarizan);
        }
    }
    
}

クラスの定義部分と実行部分を別の名前空間にして、実行部分では名前空間で修飾して、クラスを使っています。すべてが一個のファイルになっています。

using System;
namespace NMSSisokuenzan
{
    class SisokuEnzan
    {
        int firstNumber;
        int secondNumber;
        int wa;
        int sa;
        int seki;
        double waru;
        public SisokuEnzan(int x, int y)
        {
            firstNumber = x;
            secondNumber = y;
        }
        public void Kasan()
        {
            wa = firstNumber + secondNumber;
        }
        public void Genzan()
        {
            sa = firstNumber - secondNumber;
        }
        public void Kakezan()
        {
            seki = firstNumber * secondNumber;
        }
        public void Warizan()
        {
            waru = (double)firstNumber / secondNumber;
        }
        public int PKasan
        {
            get
            {
                return wa;
            }
        }
        public int PGenzan
        {
            get
            {
                return sa;
            }
        }
        public int PKakezan
        {
            get
            {
                return seki;
            }
        }

        public double PWarizan
        {
            get
            {
                return waru;
            }
        }
    }
}
using System;

namespace SisokuEnzanDemo
{ 
    class EnzanDemo
    {
        static void Main()
        {
            NMSSisokuenzan.SisokuEnzan obj = new NMSSisokuenzan.SisokuEnzan(100, 200);
            obj.Kasan(); obj.Genzan(); obj.Kakezan(); obj.Warizan();
            Console.WriteLine(obj.PKasan);
            Console.WriteLine(obj.PGenzan);
            Console.WriteLine(obj.PKakezan);
            Console.WriteLine(obj.PWarizan);
        }
    }
    
}

クラスの定義部分と実行部分を別の名前空間にして、実行部分では名前空間で修飾して、クラスを使っています。今回はファイルを分けました。でも、名前空間でクラス名を修飾は同じ。

using System;
using NMSSisokuenzan;

namespace SisokuEnzanDemo
{ 
    class EnzanDemo
    {
        static void Main()
        {
            SisokuEnzan obj = new SisokuEnzan(100, 200);
            obj.Kasan(); obj.Genzan(); obj.Kakezan(); obj.Warizan();
            Console.WriteLine(obj.PKasan);
            Console.WriteLine(obj.PGenzan);
            Console.WriteLine(obj.PKakezan);
            Console.WriteLine(obj.PWarizan);
        }
    }  
}

クラスの定義部分と実行部分を別の名前空間にして、別ファイルです。今回は名前空間でクラスを修飾で無くて、先頭部分にusing使うことで、修飾を省いてます。クラスの定義部分は同じです。これをusingディレクティブというようです。

using System;
//using NMSSisokuenzan;
namespace SisokuEnzanDemo
{
    using MyNS = NMSSisokuenzan.SisokuEnzan;
    class EnzanDemo
    {
         
        static void Main()
        {
            MyNS objMyNS = new MyNS(100, 200);

            //SisokuEnzan obj = new SisokuEnzan(100, 200);
            objMyNS.Kasan(); objMyNS.Genzan(); objMyNS.Kakezan(); objMyNS.Warizan();
            Console.WriteLine(objMyNS.PKasan);
            Console.WriteLine(objMyNS.PGenzan);
            Console.WriteLine(objMyNS.PKakezan);
            Console.WriteLine(objMyNS.PWarizan);
        }
    }  
}

 using ディレクティブのもう一つの形ということで、MyNSはNMSSisokuenzan.SisokukEnzanのエイリアスというようです。少し混乱気味です。”(-“”-)”

カテゴリー
C

独習C#第3版、P460 usingディレクティブ

// カウンタのための名前空間を宣言
namespace Counter
{
    // 簡単なカウントダウン用のカウンタ
    class CountDown
    {
        int val;

        public CountDown(int n) { val = n; }

        public void Reset(int n)
        {
            val = n;
        }

        public int Count()
        {
            if (val > 0) return val--;
            else return 0;
        }
    }
}
using System;
using Counter;

namespace ConsoleApp1
{
    class Program
    {
        public static void Main()
        {
            CountDown cd1 = new CountDown(10); 
            //←CountDownクラスがCounter名前空間で修飾されている
            int i;

            do
            {
                i = cd1.Count();
                Console.Write(i + " ");
            } while (i > 0);
            Console.WriteLine();

            CountDown cd2 = new CountDown(20);

            do
            {
                i = cd2.Count();
                Console.Write(i + " ");
            } while (i > 0);
            Console.WriteLine();

            cd2.Reset(4);
            do
            {
                i = cd2.Count();
                Console.Write(i + " ");
            } while (i > 0);
            Console.WriteLine();
        }
    }
}

 名前空間の違う、この場合はクラスですが、を参照するときはusingで名前空間を取り込みます?。あやふやな知識で言うとC++の場合は、ヘッダーファイルにしておいて、mainのほうでincludeするような感じですかね?名前空間が違っても参照する方法はある。

カテゴリー
C

独習C#第3版、前の例を変更しました。メンバー変数をprivate、メソッドとプロパティで変更する。

using System;

namespace Chapter01All
{
    class StringChangeInt
    {
        int kekkaInt;
        String kekkaString;
        bool kekkaBool;
        public void SetKekkaInt(int ki)
        {
            kekkaInt = ki;
        }
        public int GetKekkaInt()
        {
            return kekkaInt;
        }
        public String PkekkaString
        {
            get
            {
                return kekkaString;
            }
            set
            {
                kekkaString = value;
            }
        }
        public Boolean PkekkaBool
        {
            get
            {
                return kekkaBool;
            }
            set
            {
                kekkaBool = value;
            }
        }
    }
    interface ChangeInt
    {
        StringChangeInt ConvRoutine(String str);
    }

    class InterFaceSample: ChangeInt
    {
        public StringChangeInt ConvRoutine(String s)
        {
            StringChangeInt stci = new StringChangeInt();
            int w = 0;
            for(int i=0; i<s.Length; i++)
            {
                int work = s[i] - '0';
                if(!(work <= 0 & work >= 9)){
                    stci.SetKekkaInt(-1);
                    stci.PkekkaString = s;
                    stci.PkekkaBool = false;
                    return stci;
                }
                w = (w * 10)  + s[i] - '0';
            }
            stci.SetKekkaInt(w);
            stci.PkekkaString = "";
            stci.PkekkaBool = true;
            return stci;
        }

    }
    class InterfaceSample
    {
        static void Main()
        {
            InterFaceSample obj = new InterFaceSample();
            StringChangeInt w = new StringChangeInt();
            w = obj.ConvRoutine("100");
            if (w.PkekkaBool)
                Console.WriteLine(w.GetKekkaInt());
            else
                Console.WriteLine(w.PkekkaString);
            w = obj.ConvRoutine("ABC");
            if (w.PkekkaBool)
                Console.WriteLine(w.GetKekkaInt());
            else
                Console.WriteLine(w.PkekkaString);

        }
    }
}

 class StringChangeIntはメンバー変数が3個あります。前はpublicにしてましたが、通常privateが薦められてますので、そうすると、直接アクセスが出来なくなります。メソッドでやるとSetKekkaIntとGetKekkaIntdですし、プロパティでやるとPkekkaStringとPkekkaBoolです。今回はこれ以上は止めておきます。

カテゴリー
C

独習C#第3版、P334 インターフェイスとクラスのオブジェクトを返し値にする。

using System;

namespace Chapter01All
{
    class StringChangeInt
    {
        public int kekkaInt;
        public String kekkaString;
        public bool kekka;
    }
    interface ChangeInt
    {
        StringChangeInt Routine(String str);
        String NotConv(String str);
    }

    class InterFaceSample: ChangeInt
    {
        public StringChangeInt Routine(String s)
        {
            StringChangeInt stci = new StringChangeInt();
            int w = 0;
            for(int i=0; i<s.Length; i++)
            {
                int work;
                work = s[i] - '0';
                if(!(work <= 0 & work >= 9)){
                    stci.kekkaInt = -1;
                    stci.kekkaString = s;
                    stci.kekka = false;
                    return stci;
                }
                w = (w * 10)  + s[i] - '0';
            }
            stci.kekkaInt = w;
            stci.kekkaString = "";
            stci.kekka = true;
            return stci;
        }
        public String NotConv(String str)
        {
            return str;
        }
    }
    class InterfaceSample
    {
        static void Main()
        {
            InterFaceSample obj = new InterFaceSample();
            StringChangeInt w = new StringChangeInt();
            w = obj.Routine("100");
            if (w.kekka)
                Console.WriteLine(w.kekkaInt);
            else
                Console.WriteLine(w.kekkaString);
            w = obj.Routine("ABC");
            if (w.kekka)
                Console.WriteLine(w.kekkaInt);
            else
                Console.WriteLine(w.kekkaString);

        }
    }
}
 

 数値変換するとエラーになる場合と正常に変換できる場合いがあります。同じルーティンで処理するには、class StringChangeIntを使うしかないのか?本来であれば、というか、出力する場面でもif文を使わないで出来ればパーフェクトなんでしょうか?

カテゴリー
C

独習C#第3版、P334 インターフェイス

using System;

namespace Chapter01All
{
    interface ChangeInt
    {
        int Routine(String str);
    }

    class InterFaceSample: ChangeInt
    {
        public int Routine(String s)
        {
            int w = 0;
            for(int i=0; i<s.Length; i++)
            {
                w = (w * 10)  + s[i] - '0';
            }
            return w;
        }
    }
    class InterfaceSample
    {
        static void Main()
        {
            InterFaceSample obj = new InterFaceSample();
            Console.WriteLine(obj.Routine("100"));
            Console.WriteLine(obj.Routine("200"));
        }
    }
}
using System;

namespace Chapter01All
{
    interface ChangeInt
    {
        int Routine(String str);
        String NotConv(String str);
    }

    class InterFaceSample: ChangeInt
    {
        public int Routine(String s)
        {
            int w = 0;
            for(int i=0; i<s.Length; i++)
            {
                w = (w * 10)  + s[i] - '0';
            }
            return w;
        }
        public String NotConv(String str)
        {
            return str;
        }
    }
    class InterfaceSample
    {
        static void Main()
        {
            InterFaceSample obj = new InterFaceSample();
            Console.WriteLine(obj.Routine("100"));
            Console.WriteLine(obj.NotConv("ABC"));
        }
    }
}

 interfaceキーワードを使うと、クラスのプロトタイプのようなもので、クラスの形態のみを定義するようです。実際にクラスを作るときは、継承のように行って、メソッドも含めて書いていくようです。文字列に数値に変換できないものがあったらどうなるのか?interface ChangeIntのメンバーが2つにはなりましたが?

カテゴリー
C

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

using System;

namespace Chapter01All
{
    class DelegateCalcs
    {
        delegate void MyEventHandler(int a, int b);
        class MyEvent
        {
            public event MyEventHandler SomeEvent;
            public void Fire(int a, int b)
            {
                if (SomeEvent != null)
                    SomeEvent(a, b);
            }
        }
        class X
        {
            public void  Xhandler(int a, int b)
            {
                Console.WriteLine("和:" + (a + b));
            }
        }
        class Y
        {
            public void Yhandler(int a, int b)
            {
                Console.WriteLine("差:" + (a - b));
            }
        }
        class EventDemo
        {
            static void Handler(int a, int b)
            {
                Console.WriteLine("積:"+( a * b));
            }
              static void Main()
            {
                MyEvent evt = new MyEvent();
                X xOb = new X();
                Y yOb = new Y();
                evt.SomeEvent += xOb.Xhandler;
                evt.SomeEvent += yOb.Yhandler;
                evt.SomeEvent += Handler;
                evt.Fire(5, 10);
                Console.WriteLine();
                evt.Fire(10, 20);
            }
        }
    }
}

 和、差、積でやって見ましたが、本質が分かってないので、例題に沿って、組み込んでみました。delegate宣言がvoidであること、FireとSomeEventの関係などが分かってませんね。

カテゴリー
C

VS2019C#で名前空間を同じにする

// カウンタのための名前空間を宣言
namespace ConsoleApp1 
{
    // 簡単なカウントダウン用のカウンタ
    class CountDown
    {
        int val;

        public CountDown(int n) { val = n; }

        public void Reset(int n)
        {
            val = n;
        }

        public int Count()
        {
            if (val > 0) return val--;
            else return 0;
        }
    }
}
namespace ConsoleApp1
{
    class Program
    {
        public static void Main()
        {
            CountDown cd1 = new CountDown(10); 
            //←CountDownクラスがCounter名前空間で修飾されている、
      //必要がなくなった。
            int i;

            do
            {
                i = cd1.Count();
                Console.Write(i + " ");
            } while (i > 0);
            Console.WriteLine();

            CountDown cd2 = new CountDown(20);

            do
            {
                i = cd2.Count();
                Console.Write(i + " ");
            } while (i > 0);
            Console.WriteLine();

            cd2.Reset(4);
            do
            {
                i = cd2.Count();
                Console.Write(i + " ");
            } while (i > 0);
            Console.WriteLine();
        }
    }
}

上の上のコードでnamespaceがCounterとなっていたのを、両方のコードを同じnamespaceのConsoleApp1にすると、CountDownの修飾が必要なくなります。

カテゴリー
C

独習C#第3版、P456 名前空間

using System;

namespace Chapter01All
{// カウンタのための名前空間を宣言
    namespace Counter
    {
        // 簡単なカウントダウン用のカウンタ
        class CountDown
        {
            int val;

            public CountDown(int n) { val = n; }

            public void Reset(int n)
            {
                val = n;
            }

            public int Count()
            {
                if (val > 0) return val--;
                else return 0;
            }
        }
    }
}

using System;

namespace Chapter01All
{
    //名前空間の例

    using System;

    class NSDemo
    {
        public static void Main()
        {
            Counter.CountDown cd1 = new Counter.CountDown(10); 
            //↑矢印CountDownクラスがCounter名前空間で修飾されている
            int i;

            do
            {
                i = cd1.Count();
                Console.Write(i + " ");
            } while (i > 0);
            Console.WriteLine();

            Counter.CountDown cd2 = new Counter.CountDown(20);

            do
            {
                i = cd2.Count();
                Console.Write(i + " ");
            } while (i > 0);
            Console.WriteLine();

            cd2.Reset(4);
            do
            {
                i = cd2.Count();
                Console.Write(i + " ");
            } while (i > 0);
            Console.WriteLine();
        }
    }

}

 独習C#第3版では上のコードでのnamespace Chapter01Allで括るところは無いんですが、上の両方のコードを同じnamespaceに入れているので、問題なく動くようです。独習C#第3版のサンプルのプロジェクトの構成が、VSの通常のファイル構成と違っています。普通にやれば、アプリケーション単位のファイル構成ですが、独習C#第3版のファイル構成はチャプターごとのファイル構成で、サンプルのプログラムがまとまって入ってます。プロジェクトになれるのは一個ですので、その都度プロジェクトに入れるか、外すかしないと、Main()が2個になってエラーになります。上の様な場合は、例えば上の部分はCounter.csと下はNSDemo.csの両方をプロジェクトに入れます。Main()は1個です。

カテゴリー
C

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

// マルチキャストイベントの例
 
using System;

// イベントのためのデリゲート宣言 
delegate void MyEventHandler();

// イベントの送信側のクラス
class MyEvent {
  public event MyEventHandler SomeEvent;

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

class X {
  public void Xhandler() {
    Console.WriteLine("Event received by X object");
  }
}

class Y {
  public void Yhandler() {
    Console.WriteLine("Event received by Y object");
  }
}

class EventDemo {
  static void Handler() {
    Console.WriteLine("Event received by EventDemo");
  }

  static void Main() {  
    MyEvent evt = new MyEvent();
    X xOb = new X();
    Y yOb = new Y();

    // ハンドラをイベントリストに追加する
    evt.SomeEvent += Handler;
    evt.SomeEvent += xOb.Xhandler; //←マルチキャストのチェーンを作成する
    evt.SomeEvent += yOb.Yhandler;

    // イベントを発生させる
    evt.Fire();
    Console.WriteLine();

    // ハンドラを削除する
    evt.SomeEvent -= xOb.Xhandler;
    Console.WriteLine("After removing xOb.Xhandler");
    evt.Fire();
  }
}

 イベントは、マルチキャストにすることが出来ます。したがって、1つのイベント通知に対して複数のオブジェクトが応答することが出来る。この例には、クラスX,Yが追加されてますが、これらのクラス内で定義されるイベントハンドラーも、MyEventHandlerのデリゲート宣言文と同じ仮引数リストと戻り値を持っています。そのため、これらのハンドラーもイベントチェインに追加できます。と、解説されてます。

カテゴリー
C

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

using System;

namespace Chapter01All
{
    // とても簡単なイベントの例
    // イベント用のデリゲートの宣言
    delegate void MyEventHandler(); //←イベントで使うデリゲートを宣言する

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

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

    class EventDemo
    {
        static void Handler()
        {
            Console.WriteLine("Event fire occurred");
        }
        static void OtherHandler()
        {
            Console.WriteLine("Event water occurred");
        }


        static void Main()
        {
            MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する
            // ハンドラをイベントリストに追加する
            evt.SomeEvent += Handler; //←イベントのチェーンにハンドラを追加する
            evt.SomeEvent += OtherHandler;
            // イベントを人為的に発生させる
            evt.Fire(); //←イベントを発生させる

            OtherEvent oevt = new OtherEvent();
            oevt.anOtherEvent += OtherHandler;
            oevt.Water();
        }
    }
}

 何回か見てはいましたが、どうもピンときません。この辺がC#を理解する上での肝かもしれません。例題と同じようにイベントを一個追加して見ました。上の例では、delegateが一個しかないので、同じように動作する場合は、問題なかったのですが、動作が違うとダメだったので、もう一つのdelegateを定義したのが、下です。

using System;

namespace Chapter01All
{
    // とても簡単なイベントの例
    // イベント用のデリゲートの宣言
    delegate void MyEventHandler(); //←イベントで使うデリゲートを宣言する
    delegate void OtherMyEventHandler(String s);

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

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

    class EventDemo
    {
        static void Handler()
        {
            Console.WriteLine("Event fire occurred");
        }
        static void OtherHandler(String s)
        {
            Console.WriteLine(s);
        }


        static void Main()
        {
            MyEvent evt = new MyEvent(); //←イベントを送信する側のインスタンスを作成する
            // ハンドラをイベントリストに追加する
            evt.SomeEvent += Handler; //←イベントのチェーンにハンドラを追加する
            // イベントを人為的に発生させる
            evt.Fire(); //←イベントを発生させる

            OtherEvent oevt = new OtherEvent();
            oevt.anOtherEvent += OtherHandler;
            oevt.Water("Water Event Occurred");
        }
    }
}

イベントに引数を持たせる場合もあるでしょうから、delegateを別に作って、試行錯誤しました。

inserted by FC2 system