normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

C#でシャッフルしてみる

C#でリストをシャッフルする方法について」の議論をちょこちょこ聞いたので、ためしにシャッフルなクラスを作ってみた。
けど・・・、うーん・・・、いろいろ微妙な気がする。まずは書いたコード片を載せてみるテスト。
一応、Genericsを使ってるけど微妙なオーラが出ている。突っ込み希望。

    class Program
    {
        static void Main(string[] args)
        {
            //Cardのテスト
            Shuffle<string> s1 = new Shuffle<string>(new List<string>() {
                "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"
            }.AsQueryable());
            Console.WriteLine(string.Join(",", s1.GetN(5).ToArray()));

            //DTOにも使える
            Shuffle<SmpDto> s2 = new Shuffle<SmpDto>(new List<SmpDto>() {
                new SmpDto() { Name = "Smp1", Age = 12 },
                new SmpDto() { Name = "Smp2", Age = 16 },
                new SmpDto() { Name = "Smp3", Age = 16 },
                new SmpDto() { Name = "Smp4", Age = 16 },
                new SmpDto() { Name = "Smp5", Age = 16 },
                new SmpDto() { Name = "Smp6", Age = 22 } }.AsQueryable());
            Console.WriteLine(string.Join(",", s2.GetAll().Select(obj => obj.ToString()).ToArray()));
            Console.ReadLine();
        }
    }

    public class SmpDto
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public override string ToString()
        {
            return string.Format("[Name={0},Age={1}]",Name,Age);
        }
    }

    public class Shuffle<TModel> where TModel : class
    {
        public IQueryable<TModel> GetAll()
        {
            return GetN(_source.Count());
        }

        public IQueryable<TModel> GetN(int n)
        {
            return _source.OrderBy(obj => _rnd.Next()).Take(n);
        }

        public Shuffle(IQueryable<TModel> source)
        {
            _source = source;
        }

        protected IQueryable<TModel> _source = null;
        protected Random _rnd = new Random();
        public IQueryable<TModel> Source
        {
            get
            {
                return _source;
            }
            set
            {
                _source = value;
            }
        }
        public Random Rand
        {
            get
            {
                return _rnd;
            }
            set
            {
                _rnd = value;
            }
        }
    }