none
C# 动态声明变量吗? RRS feed

  • 问题

  • 如题!

    打个比方,我要写一个泛型的排序,输入的是一个类,排序关键字是其中的一个成员变量,这个成员基于Object。因为是泛型反射,所以我必须将比较大小能够广泛适用于所有情况。这个排序关键字可能datetime或int,也可能是string。一种传统观的做法是用typeof,结合switch来为每种类型变现一个比较大小的代码,但我觉得这样很老土、繁琐。有没有动态声明变量的方法?

    比如我通过反射知道类型是Datetime,于是我希望程序可以动态声明(new Datetime(2012,06,22)),而不是预先编译好的。

    2012年6月22日 13:46

答案

  • 理论上说,因为你是一个泛型类比较,所以反射不可避免。不过我们可以指定类型,参考:

    namespace CSharp
    {
        public class MyComparer<T,Field> : IComparer<T> where Field:IComparable
        {
            private string ColumnName { get; set; }
    
            public MyComparer(string colName)
            {
                ColumnName = colName;
            }
    
            /// <summary>
            /// 实现类比较方法
            /// </summary>
            public int Compare(T x, T y)
            {
                Field f1 = (Field)x.GetType().GetProperty(ColumnName).GetValue(x, null);
                Field f2 = (Field)y.GetType().GetProperty(ColumnName).GetValue(y, null);
                return f1.CompareTo(f2);
            }
        }
        public class MainTest
        {
            private class Student
            {
                public int StudentId { get; set; }
                public string StudentName { get; set; }
                public DateTime Birthday { get; set; }
            }
    
            static void Main(string[] args)
            {
                List<Student> students = new List<Student>();
                Random r = new Random(Guid.NewGuid().GetHashCode());
                for (int i = 1; i < 11; i++)
                {
                    students.Add(new Student { StudentId = r.Next(1, 11), StudentName = "Name" + r.Next(1, 11) ,Birthday=DateTime.Now.AddDays(r.Next(1,11))});
                }
    
                //指定字段类型和名字排序
                students.Sort(new MyComparer<Student, DateTime>("Birthday"));
    
                //输出
                foreach (var item in students)
                {
                    Console.WriteLine(item.StudentId+"<===>"+item.StudentName+"<===>"+item.Birthday.ToLongDateString());
                }
            }
        }
    }


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月23日 2:24
    版主

全部回复

  • 理论上说,因为你是一个泛型类比较,所以反射不可避免。不过我们可以指定类型,参考:

    namespace CSharp
    {
        public class MyComparer<T,Field> : IComparer<T> where Field:IComparable
        {
            private string ColumnName { get; set; }
    
            public MyComparer(string colName)
            {
                ColumnName = colName;
            }
    
            /// <summary>
            /// 实现类比较方法
            /// </summary>
            public int Compare(T x, T y)
            {
                Field f1 = (Field)x.GetType().GetProperty(ColumnName).GetValue(x, null);
                Field f2 = (Field)y.GetType().GetProperty(ColumnName).GetValue(y, null);
                return f1.CompareTo(f2);
            }
        }
        public class MainTest
        {
            private class Student
            {
                public int StudentId { get; set; }
                public string StudentName { get; set; }
                public DateTime Birthday { get; set; }
            }
    
            static void Main(string[] args)
            {
                List<Student> students = new List<Student>();
                Random r = new Random(Guid.NewGuid().GetHashCode());
                for (int i = 1; i < 11; i++)
                {
                    students.Add(new Student { StudentId = r.Next(1, 11), StudentName = "Name" + r.Next(1, 11) ,Birthday=DateTime.Now.AddDays(r.Next(1,11))});
                }
    
                //指定字段类型和名字排序
                students.Sort(new MyComparer<Student, DateTime>("Birthday"));
    
                //输出
                foreach (var item in students)
                {
                    Console.WriteLine(item.StudentId+"<===>"+item.StudentName+"<===>"+item.Birthday.ToLongDateString());
                }
            }
        }
    }


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月23日 2:24
    版主
  • 谢谢,我去试试。
    2012年6月26日 11:00
  • 谢谢,我去试试。
    欢迎再来,互帮互助!

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月27日 1:16
    版主