ラベル C# の投稿を表示しています。 すべての投稿を表示
ラベル C# の投稿を表示しています。 すべての投稿を表示

2012年11月11日日曜日

素数を求める

何やら昔書いたブログの記事にコメントがついていたので、適当にこっちに移行。
 素数を求める簡単なプログラムです。
 たぶん、簡単なプログラミングテストなどに出てくる問題となります。
 んではどうぞ(´ρ`)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace PrimeNumberConsoleApplication
{
    internal class Program
    {
        /// <summary>
        /// 素数求めるプログラム
        /// </summary>
        /// <param name="args"></param>
        private static void Main(string[] args)
        {
            // 2は決め打ち
            Console.WriteLine(@"2");
 
            // 3以上から素数を見ていくけど、偶数は全部2が約数となるので素数対象は奇数のみとなるので2でカウントアップするよ
            for (int i = 3; i <= 1000; i += 2)
            {
                bool hasOuputTarget = true;
 
                // 素数指定で使用する対象の割り切れる数は、対象のiの平方根以下となる。
                // これ以上の割り切れる数となると、平方根以下の約数かける平方根以上の約数の組み合わせしか無い為である。
                // 約数の最小値から検索を初めて、iの平方根までで割り切れない場合は、素数となる
                // 2でカウントアップしてるのは、偶数は見る意味が無い為である。っというかiが奇数のみの場合、偶数でのあまりの確認が必要ない為である。
                for (int j = 3; j <= Math.Sqrt(i); j += 2)
                {
                    if (i % j == 0)
                    {
                        hasOuputTarget = false;
                        break;
                    }
                }
 
                if (hasOuputTarget)
                    Console.WriteLine(i.ToString());
            }
 
            Console.ReadLine();
        }
    }
}

2012年10月31日水曜日

DataGridViewとEntityその2

いくつか間抜けな事をしでかしていたので、ざっくり修正。

属性クラス

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace EntitySortSample
{
    /// <summary>
    /// ソート用のEntityに追加するプロパティです。
    /// 単一プロパティによるソートを行った場合、同値だった場合に指定する別プロパティのソートKeyを定義します。
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class SortAttribute : Attribute
    {
        /// <summary>
        /// ソート対象となるプロパティの格納を行っているフィールド
        /// </summary>
        private List<string> _properties;
 
        /// <summary>
        /// ソート対象のプロパティを取得します。
        /// </summary>
        public List<string> Properties { get { return this._properties; } }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="properties">比較に仕様する追加プロパティ名</param>
        public SortAttribute(string[] properties)
        {
            this._properties = properties.ToList<string>();
        }
    }
}



ソート方法を実装したIComparer<T>の実装
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
 
namespace EntitySortSample
{
    /// <summary>
    /// IComparer<T>の実装です。
    /// なお、ソート処理対象のプロパティに配列が使用されているような場合は正常に動作しません。
    /// インデクサも同様です。
    /// もっとも、プロパティに配列を使うなという事を一言記載。
    ///
    /// また、プロパティに指定する型は、必ずIComparableの実装が必要となります。
    /// これは、プロパティの値を比較する際に、ジェネリックメソッドにより、ComparableToにて大小比較を行っている為です。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ComparerEx<T> : IComparer<T>
    {
        /// <summary>
        /// ソート対象のプロパティ名
        /// </summary>
        private PropertyDescriptor _propertyDescriptor;
 
        /// <summary>
        /// ソート対象をソートする際のソート方向
        /// </summary>
        private ListSortDirection _listSortDirection;
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="propertyDescriptor">ソート対象のプロパティ</param>
        /// <param name="listSortDirecton">ソート方向</param>
        public ComparerEx(PropertyDescriptor propertyDescriptor, ListSortDirection listSortDirection)
        {
            this._propertyDescriptor = propertyDescriptor;
            this._listSortDirection = listSortDirection;
        }
 
        /// <summary>
        /// ソート処理で必要な大小比較を行い、処理結果により
        /// マイナス値~プラス値までを戻します。
        /// 完全な同一値の場合は0を返します。
        /// </summary>
        /// <param name="x">比較対象のオブジェクト1です。</param>
        /// <param name="y">比較対象のオブジェクト2です。</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        public int Compare(T x, T y)
        {
            var xPropertyInfo = this.GetPropertyInfo(x, this._propertyDescriptor.Name);
            var yPropertyInfo = this.GetPropertyInfo(y, this._propertyDescriptor.Name);
 
            var xValue = xPropertyInfo.GetValue(x, null);
            var yValue = yPropertyInfo.GetValue(y, null);
 
            var comparableRet = this.Comparable((IComparable)xValue, (IComparable)yValue);
 
            if (comparableRet != 0)
                return comparableRet;
 
            // 同値の場合、PropertyInfoの属性に追加ソート指定項目が存在するかを確認する。
            var xAttributes = xPropertyInfo.GetCustomAttributes(typeof(SortAttribute), false);
            if (xAttributes == null)
                return comparableRet;
 
            // 属性が存在する場合、内部にSortAttributeが定義されているかを確認する。
            foreach (var xAttribute in xAttributes)
            {
                var sortAttribute = xAttribute as SortAttribute;
 
                if (sortAttribute == null)
                    continue;
 
                // SortAttributeの定義が存在する場合は、対象の属性情報に定義されている比較対象の予備プロパティ名を順番に比較していく。
                foreach (var propertyName in sortAttribute.Properties)
                {
                    comparableRet = this.CompareSub(x, y, propertyName);
                    if (comparableRet != 0)
                        return comparableRet;
                }
            }
 
            // ここまで抜けてきた場合は、完全同値の値となる。
            return 0;
        }
 
        /// <summary>
        /// ソート処理で必要な大小比較を行い、処理結果により
        /// マイナス値~プラス値までを戻します。
        /// 完全な同一値の場合は0を返します。
        /// </summary>
        /// <param name="x">比較対象のオブジェクト1です。</param>
        /// <param name="y">比較対象のオブジェクト2です。</param>
        /// <param name="propertyName">比較対象のプロパティです。</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        private int CompareSub(T x, T y, string propertyName)
        {
            var xPropertyInfo = this.GetPropertyInfo(x, propertyName);
            var yPropertyInfo = this.GetPropertyInfo(y, propertyName);
 
            var xValue = xPropertyInfo.GetValue(x, null);
            var yValue = yPropertyInfo.GetValue(y, null);
 
            return this.Comparable((IComparable)xValue, (IComparable)yValue);
        }
 
        /// <summary>
        /// 指定された型に格納されているPropertyInfoの取得を行います。
        /// </summary>
        /// <param name="target">プロパティの情報を取得する対象</param>
        /// <param name="propertyName">取得対象のプロパティ名</param>
        /// <returns></returns>
        private PropertyInfo GetPropertyInfo(T target, string propertyName)
        {
            var propertyInfo = target.GetType().GetProperty(propertyName);
            if (propertyInfo == null)
                throw new ArgumentException(@"指定されてプロパティ名の取得が行えませんでした。");
 
            return propertyInfo;
        }
 
        /// <summary>
        /// 大小比較用のジェネリックメソッドです。
        /// </summary>
        /// <typeparam name="T">比較する型</typeparam>
        /// <param name="x">比較対象の値1</param>
        /// <param name="y">比較対象の値2</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        private int Comparable<T2>(T2 x, T2 y) where T2 : IComparable
        {
            var buf = x.CompareTo(y);
 
            if (this._listSortDirection == ListSortDirection.Ascending)
                return buf;
 
            return buf * -1;
        }
    }
}



最後にBindingListの拡張

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
 
namespace EntitySortSample
{
    /// <summary>
    /// BindingListの拡張クラスです。
    /// </summary>
    /// <typeparam name="T">タイプ</typeparam>
    public class BindingListEx<T> : BindingList<T>
    {
        /// <summary>
        /// ソート項目
        /// </summary>
        private PropertyDescriptor _propertyDescriptor;
 
        /// <summary>
        /// ソート方向(昇順・降順)の保持を行います。
        /// </summary>
        private ListSortDirection _listSortDirection;
 
        /// <summary>
        /// ソート済みかを示す値
        /// </summary>
        private bool _isSortedCore = false;
 
        /// <summary>
        /// ソートのサポートを行う事を宣言
        /// </summary>
        protected override bool SupportsSortingCore
        {
            get
            {
                return true;
            }
        }
 
        /// <summary>
        /// リストのソート順
        /// </summary>
        protected override ListSortDirection SortDirectionCore
        {
            get
            {
                return this._listSortDirection;
            }
        }
 
        /// <summary>
        /// ソート対象
        /// </summary>
        protected override PropertyDescriptor SortPropertyCore
        {
            get
            {
                return this._propertyDescriptor;
            }
        }
 
        /// <summary>
        /// ソート済みかを示す値の取得用
        /// </summary>
        protected override bool IsSortedCore
        {
            get
            {
                return this._isSortedCore;
            }
        }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public BindingListEx()
            : base()
        {
        }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="list"></param>
        public BindingListEx(IList<T> list)
            : base(list)
        {
        }
 
        /// <summary>
        /// ソート処理
        /// </summary>
        /// <param name="prop">ソート項目</param>
        /// <param name="direction">ソート方向</param>
        protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
        {
            // ソート方向とソートプロパティを格納
            this._propertyDescriptor = prop;
            this._listSortDirection = direction;
 
            // Itemsの存在が無い場合は、処理必要な処理のみ実行して処理を戻します。
            if (base.Items == null || base.Items.Count == 0)
            {
                this._isSortedCore = false;
                base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, prop));
 
                return;
            }
 
            // Itemsが存在する場合はComparerExを生成して、比較処理を実行します。
            var items = (List<T>)base.Items;
            var comparerEx = new ComparerEx<T>(this._propertyDescriptor, this._listSortDirection);
            items.Sort(comparerEx);
 
            // ソート処理の終了を設定
            this._isSortedCore = true;
            base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, prop));
 
            return;
        }
    }
} 

2012年10月25日木曜日

DataGridViewとEntity

毎度毎度EntityをDataGridにぶち込んだ際に、ソート処理を実装するので、ある程度のサンプルをこちらに記載。

自分用の備忘録で、未テストの適当コードなので注意。

あとでテスト済みをソリューション毎乗っけるかもしれない?

BindingListの拡張

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
 
namespace EntityFrameworkSample
{
    /// <summary>
    /// BindingListの拡張クラスです。
    /// </summary>
    /// <typeparam name="T">タイプ</typeparam>
    public class BindingListEx<T> : BindingList<T>
    {
        /// <summary>
        /// ソート項目
        /// </summary>
        private PropertyDescriptor _propertyDescriptor;
 
        /// <summary>
        /// ソート方向(昇順・降順)の保持を行います。
        /// </summary>
        private ListSortDirection _listSortDirection;
 
        /// <summary>
        /// ソート済みかを示す値
        /// </summary>
        private bool _isSortedCore = false;
 
        /// <summary>
        /// ソートのサポートを行う事を宣言
        /// </summary>
        protected override bool SupportsSortingCore
        {
            get
            {
                return true;
            }
        }
 
        /// <summary>
        /// リストのソート順
        /// </summary>
        protected override ListSortDirection SortDirectionCore
        {
            get
            {
                return this._listSortDirection;
            }
        }
 
        /// <summary>
        /// ソート対象
        /// </summary>
        protected override PropertyDescriptor SortPropertyCore
        {
            get
            {
                return this._propertyDescriptor;
            }
        }
 
        /// <summary>
        /// ソート済みかを示す値の取得用
        /// </summary>
        protected override bool IsSortedCore
        {
            get
            {
                return this._isSortedCore;
            }
        }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public BindingListEx()
            : base()
        {
        }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="list"></param>
        public BindingListEx(IList<T> list)
            : base(list)
        {
        }
 
        /// <summary>
        /// ソート処理
        /// </summary>
        /// <param name="prop">ソート項目</param>
        /// <param name="direction">ソート方向</param>
        protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
        {
            // ソート方向とソートプロパティを格納
            this._propertyDescriptor = prop;
            this._listSortDirection = direction;
 
            // Itemsの存在が無い場合は、処理必要な処理のみ実行して処理を戻します。
            if (base.Items == null || base.Items.Count == 0)
            {
                this._isSortedCore = false;
                base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, prop));
 
                return;
            }
 
            // Itemsが存在する場合はComparerExを生成して、比較処理を実行します。
            var items = (List<T>)base.Items;
            var comparerEx = new ComparerEx<T>(this._propertyDescriptor, this._listSortDirection);
            items.Sort(comparerEx);
 
            // ソート処理の終了を設定
            this._isSortedCore = true;
            base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, prop));
 
            return;
        }
    }
}


IComparerの実装

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
 
namespace EntityFrameworkSample
{
    /// <summary>
    /// IComparer<T>の実装です。
    /// なお、ソート処理対象のプロパティに配列が使用されているような場合は正常に動作しません。
    /// インデクサも同様です。
    /// もっとも、プロパティに配列を使うなという事を一言記載。
    ///
    /// また、プロパティに指定する型は、必ずIComparableの実装が必要となります。
    /// これは、プロパティの値を比較する際に、ジェネリックメソッドにより、ComparableToにて大小比較を行っている為です。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ComparerEx<T> : IComparer<T>
    {
        /// <summary>
        /// ソート対象のプロパティ名
        /// </summary>
        private PropertyDescriptor _propertyDescriptor;
 
        /// <summary>
        /// ソート対象をソートする際のソート方向
        /// </summary>
        private ListSortDirection _listSortDirection;
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="propertyDescriptor">ソート対象のプロパティ</param>
        /// <param name="listSortDirecton">ソート方向</param>
        public ComparerEx(PropertyDescriptor propertyDescriptor, ListSortDirection listSortDirection)
        {
            this._propertyDescriptor = propertyDescriptor;
            this._listSortDirection = listSortDirection;
        }
 
        /// <summary>
        /// ソート処理で必要な大小比較を行い、処理結果により
        /// マイナス値~プラス値までを戻します。
        /// 完全な同一値の場合は0を返します。
        /// </summary>
        /// <param name="x">比較対象のオブジェクト1です。</param>
        /// <param name="y">比較対象のオブジェクト2です。</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        public int Compare(T x, T y)
        {
            var xPropertyInfo = this.GetPropertyInfo(x, this._propertyDescriptor.Name);
            var yPropertyInfo = this.GetPropertyInfo(y, this._propertyDescriptor.Name);
 
            var xValue = xPropertyInfo.GetValue(x, null);
            var yValue = yPropertyInfo.GetValue(y, null);
 
            var comparableRet = this.Comparable((IComparable)xValue, (IComparable)yValue);
 
            if (comparableRet != 0)
                return comparableRet;
 
            // 同値の場合、PropertyInfoの属性に追加ソート指定項目が存在するかを確認する。
            var xAttributes = xPropertyInfo.GetCustomAttributes(typeof(SortAttribute), false);
            if (xAttributes == null)
                return comparableRet;
 
            // 属性が存在する場合、内部にSortAttributeが定義されているかを確認する。
            foreach (var xAttribute in xAttributes)
            {
                var sortAttribute = xAttribute as SortAttribute;
 
                if (sortAttribute == null)
                    continue;
 
                // SortAttributeの定義が存在する場合は、対象の属性情報に定義されている比較対象の予備プロパティ名を順番に比較していく。
                foreach (var propertyName in sortAttribute.Properties)
                {
                    comparableRet = this.CompareSub(x, y, propertyName);
                    if (comparableRet != 0)
                        return comparableRet;
                }
            }
 
            // ここまで抜けてきた場合は、完全同値の値となる。
            return 0;
        }
 
        /// <summary>
        /// ソート処理で必要な大小比較を行い、処理結果により
        /// マイナス値~プラス値までを戻します。
        /// 完全な同一値の場合は0を返します。
        /// </summary>
        /// <param name="x">比較対象のオブジェクト1です。</param>
        /// <param name="y">比較対象のオブジェクト2です。</param>
        /// <param name="propertyName">比較対象のプロパティです。</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        private int CompareSub(T x, T y, string propertyName)
        {
            var xPropertyInfo = this.GetPropertyInfo(x, propertyName);
            var yPropertyInfo = this.GetPropertyInfo(y, propertyName);
 
            var xValue = xPropertyInfo.GetValue(x, null);
            var yValue = yPropertyInfo.GetValue(y, null);
 
            return this.Comparable((IComparable)xValue, (IComparable)yValue);
        }
 
        /// <summary>
        /// 指定された型に格納されているPropertyInfoの取得を行います。
        /// </summary>
        /// <param name="target">プロパティの情報を取得する対象</param>
        /// <param name="propertyName">取得対象のプロパティ名</param>
        /// <returns></returns>
        private PropertyInfo GetPropertyInfo(T target, string propertyName)
        {
            var propertyInfo = target.GetType().GetProperty(propertyName);
            if (propertyInfo == null)
                throw new ArgumentException(@"指定されてプロパティ名の取得が行えませんでした。");
 
            return propertyInfo;
        }
 
        /// <summary>
        /// 大小比較用のジェネリックメソッドです。
        /// </summary>
        /// <typeparam name="T">比較する型</typeparam>
        /// <param name="x">比較対象の値1</param>
        /// <param name="y">比較対象の値2</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        private int Comparable<T>(T x, T y) where T : IComparable
        {
            var buf = x.CompareTo(y);
 
            if (this._listSortDirection == ListSortDirection.Ascending)
                return buf;
 
            return buf * -1;
        }
    }
}


複数プロパティでのソートする際に仕様するカスタム属性の作成

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace EntityFrameworkSample
{
    /// <summary>
    /// ソート用のEntityに追加するプロパティです。
    /// 単一プロパティによるソートを行った場合、同値だった場合に指定する別プロパティのソートKeyを定義します。
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class SortAttribute : Attribute
    {
        /// <summary>
        /// ソート対象となるプロパティの格納を行っているフィールド
        /// </summary>
        private List<string> _properties;
 
        /// <summary>
        /// ソート対象のプロパティを取得します。
        /// </summary>
        public List<string> Properties { get { return this._properties; } }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="properties">比較に仕様する追加プロパティ名</param>
        public SortAttribute(string[] properties)
        {
            this._properties = properties.ToList<string>();
        }
    }
}

とりあえず、ざっくり記載。
テストした後の修正バージョンを乗っけるかは、要望次第かも?

2012年9月16日日曜日

Microsoft Enterprise Library 5.0のサンプル

Microsoft Enterprise Library 5.0のインストールが完了しましたが、そもそもどうやって使うんだ?
っという問題にぶち当たると思います。

ってことで今度はサンプルをインストールしましょう。

http://www.microsoft.com/en-us/download/details.aspx?id=6932

上記URLからHands-On Labs for Microsoft Enterprise Library 5.0をダウンロードします。

そしてまたてけてけてんっとインストールを行います。


おとなしく次へと進みます。


同じくおとなしく次へと進みます。


サンプルの言語を選択します。ここは個人の好みでいいと思います。
私は画面にあるように両方を選択してインストールを行いました。


インストールするものとディレクトリを選択します。
全部デフォルトでいいと思います。


素直にインストールします。


おとなしく待ちます。





終わったので、インストール先を確認してみましょう。


上記のようにHands On Labsがインストールされてれば大丈夫です。


さて、次回からは、サンプルとその他を見ながら実際の使い方をお勉強です。

Microsoft Enterprise Library 5.0のインストール

Microsoft Enterprise Library 5.0ってどうよって言ってみましたが、わからないなら使ってみよう、そうしよう。
ってことで今回インストール方法からスタート。

まずはダウンロード
http://www.microsoft.com/en-us/download/details.aspx?id=15104

上記のURLからインストーラーを落としてきます。

ダウンロードしたファイルを開くと、Enterprise Libraryのインストールが開始されます


ダウンロードしたファイルを実行すると上記のようにインストーラーが開始されるので、以下画像の手順通りで問題なければ、インストールをてけてけてんっと進めていきます。


ソースコードが必要な場合は、ここでソースコードのインストールをするようにしておいてください。
中身をちらちら見てみたいので、とりあえず私はインストールをしておきました。


インストールをこのまま行います。


しばらくまつとインストールが完了して、ソースのインストールに移ります。


ソースファイルのインストール先を選択できますので、てけてけてんとインストールを行います。


これで本体のインストールはひとまず完了です。

続けて次の記事でサンプルのインストールを行います。