分类目录归档:C#

DataTableSerializer datatable序列化成对象 datatable to entity serialization

public class DataTableSerializer
{
  public static List ToList(DataTable dt)
  {
    var list = new List();
    if (dt == null || dt.Rows.Count == 0)
      return list;//return empty list instead of null object
    list.AddRange(from DataRow row in dt.Rows select ToEntity(row));
    return list;
  }
  public static T ToEntity( DataRow row)
  {
    var objType = typeof(T);
    var obj = Activator.CreateInstance();
    foreach (DataColumn column in row.Table.Columns)
    {
      var property = objType.GetProperty(column.ColumnName,
          BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
      if (property == null || !property.CanWrite)
      {
        continue;
      }
      var value = row[column.ColumnName];
      if (value == DBNull.Value)
      {
        value = null;
      }
      else
      {
        //add what you need.
        //if (column.DataType == typeof (DateTime))
        //{
        //    value = ((DateTime)value).ToString("yyyy-MM-dd");
        //}
      }
      property.SetValue(obj, value, null);
    }
    return obj;
  }
}

用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树

这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力。曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用。今天我尝试用简单的方法叙述一下,让大家在五分钟内看完这篇博客。

第一分钟:委托

  有些教材,博客说到委托都会提到事件,虽然事件是委托的一个实例,但是为了理解起来更简单,今天只谈委托不谈事件。先上一段代码:

下边的代码,完成了一个委托应用的演示。一个委托分三个步骤:

public partial class WebForm3 : System.Web.UI.Page
{
    //step01:首先用delegate定义一个委托 。
    public delegate int CalculatorAdd(int x, int y);
    protected void Page_Load(object sender, EventArgs e)
    {
        //step03:用这个方法来实例化这个委托。
        CalculatorAdd cAdd = new CalculatorAdd(Add);
        //int result = cAdd(5, 6);
        int result = cAdd.Invoke(5,6);
    }
    // step02:声明一个方法来对应委托。
    public int Add(int x, int y)
    {
        return x + y;
    }
}

step01:首先用delegate定义一个委托?。

step02:声明一个方法来对应委托。

step03:用这个方法来实例化这个委托。

至此,一个委托的应该就完成了,就可以调用委托了。

第二分钟:匿名方法

  在上一分钟已经知道了,完成一个委托应用分三步走,缺一步都不行,如果要跨大步,当心步子大了扯着蛋。但是微软不怕扯着蛋,非要把三步做成两步来走啊!所以微软就用匿名方法来简化上边的三个步骤。匿名方法这个玩意儿怎么说呢,在C#中完全是可有可无的东西,只是为C#锦上添花,有人别出心裁给它取个名字叫语法糖。

public partial class WebForm3 : System.Web.UI.Page
{
    //step01:首先用delegate定义一个委托
    public delegate int CalculatorAdd(int x, int y);
    protected void Page_Load(object sender, EventArgs e)
    {
        //step02:用这样的写法 delegate(int x, int y) { return x + y; },把一个方法赋值给委托
        CalculatorAdd cAdd = delegate(int x, int y) { return x + y; };
        int result = cAdd.Invoke(5, 6);
    }
}

step01:首先用delegate定义一个委托 。

step02:用这样的写法 delegate(int x, int y) { return x + y; },把一个方法赋值给委托,其实这种写法就是匿名方法。

这时会惊奇的发现,这不是三步当着两步走了哇?

第三分钟:Lambda表达式

  原本很简单的程序,加上几个delegate关键字,这代码一下就变得深奥了,深奥的东西懂的人就变少了,所以这个还可以作为加薪的筹码。但是微软对C#的设计理念是简单易用。微软就想方设法的来简化delegate(int x, int y) { return x + y; }这个匿名方法,Lambda就出现了。下边我来看几种lambda表达式的写法:

public partial class WebForm3 : System.Web.UI.Page
{
    public delegate int CalculatorAdd(int x, int y);
    protected void Page_Load(object sender, EventArgs e)
    {
        //方法一:
        CalculatorAdd cAdd1 = (int x, int y) => { return x + y; };
        int result1 = cAdd1(5, 6);
        //方法二:
        CalculatorAdd cAdd2 = (x, y) => { return x + y; };
        int result2 = cAdd2(5, 6);
        //方法三:
        CalculatorAdd cAdd3 = (x, y) => x + y;
        int result3 = cAdd2(5, 6);
    }
}

方法一:简单的把delegate去掉,在()与{}之间加上? “=>”。

方法二:在方法一的基础上把参数类型都干掉了。

方法三:要干就干彻底些,把{},以及return关键字都去掉了。

这几种方法随便怎么写都行,不过就是害苦了初学者,一会儿看到这种写法,一会儿看到那种写法,把人搞的神魂颠倒人,如果没人指点,确实会迷糊,难就难在这儿。

第四分钟:泛型委托

  随着.net版本的不升级,新版本总要区别于旧版本吧,不然微软的工程师怎么向他们的老大交差呀?所以微软又来玩新花样了。

public partial class WebForm3 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //方法一:
        Func cAdd1 = (int x, int y) => { return x + y; };
        int result1 = cAdd1(5, 6);
        //方法二:
        Func cAdd2 = (x, y) => { return x + y; };
        int result2 = cAdd2(5, 6);
        //方法三:
        Func cAdd3 = (x, y) => x + y;
        int result3 = cAdd2(5, 6);
    }
}

  不管是匿名方法还是Lambda表达式,完成一个委托的应用,都逃不过两个步骤,一步是定义一个委托,另一步是用一个方法来实例化一个委托。?微软干脆把这两步都合成一步来走了。用Func来简化一个委托的定义。

  至此一个委托的应用就可用? Func<int, int, int> cAdd3 = (x, y) => x + y;?这样一句话来完成了,其中的Func就是所谓的泛型委托。

第五分钟:表达式树

  表达式树其实与委托已经没什么关系了,非要扯上关系,那就这么说吧,表达式树是存放委托的容器。如果非要说的更专业一些,表达式树是存取Lambda表达式的一种数据结构。要用Lambda表达式的时候,直接从表达式中获取出来,Compile()就可以直接用了。如下代码:

public partial class WebForm3 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Expression> exp = (x, y) => x + y;
        Func fun = exp.Compile();
        int result = fun(2, 3);
    }
}

  五分钟结束了,我点到的很肤浅,但至少让大家再温习了一篇委托,匿名方法,Lambda,泛型委托,表达式树

LINQ中.AsEnumerable() 和 .ToList() 的区别:

  • .AsEnumerable()延迟执行,不会立即执行。当你调用.AsEnumerable()的时候,实际上什么都没有发生。
  • .ToList()立即执行
  • 当你需要操作结果的时候,用.ToList(),否则,如果仅仅是用来查询不需要进一步使用结果集,并可以延迟执行,就用.AsEnumerable()/IEnumerable /IQueryable
  • .AsEnumerable()虽然延迟执行,但还是访问数据库,而.ToList()直接取得结果放在内存中。比如我们需要显示两个部门的员工时,部门可以先取出放置在List中,然后再依次取出各个部门的员工,这时访问的效率要高一些,因为不需要每次都访问数据库去取出部门。
  • IQueryable实现了IEnumberable接口。但IEnumerable 换成IQueryable后速度提高很多。原因:
    IQueryable接口与IEnumberable接口的区别: IEnumerable 泛型类在调用自己的SKip 和 Take 等扩展方法之前数据就已经加载在本地内存里了,而IQueryable 是将Skip ,take 这些方法表达式翻译成T-SQL语句之后再向SQL服务器发送命令,它并不是把所有数据都加载到内存里来才进行条件过滤。
  • IEnumerable跑的是Linq to Object,强制从数据库中读取所有数据到内存先。

C#从文件byte[]获取文件mime(contentType)

public class MimeHelper
    {
        public static int MimeSampleSize = 256;
        public static string DefaultMimeType = "application/octet-stream";
        [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
        private extern static System.UInt32 FindMimeFromData(
            System.UInt32 pBC,
            [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl,
            [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
            System.UInt32 cbSize,
            [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed,
            System.UInt32 dwMimeFlags,
            out System.UInt32 ppwzMimeOut,
            System.UInt32 dwReserverd
        );
        public static string GetMimeFromBytes(byte[] data)
        {
            try
            {
                uint mimeType;
                FindMimeFromData(0, null, data, (uint)MimeSampleSize, null, 0, out mimeType, 0);
                var mimePointer = new IntPtr(mimeType);
                var mime = Marshal.PtrToStringUni(mimePointer);
                Marshal.FreeCoTaskMem(mimePointer);
                return mime ?? DefaultMimeType;
            }
            catch
            {
                return DefaultMimeType;
            }
        }
    }

C#中汉字排序简单示例(拼音/笔划)


class Program
    {
        static void Main(string[] args)
        {
            string[] arr = { "趙(ZHAO)", "錢(QIAN)", "孫(SUN)", "李(LI)", "周(ZHOU)", "吳(WU)", "鄭(ZHENG)", "王(WANG)"};
            //发音 LCID:0x00000804
            CultureInfo PronoCi = new CultureInfo(2052);
            //Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us");
            Array.Sort(arr);
            Console.WriteLine("按发音排序:");
            for (int i = arr.GetLowerBound(0); i <= arr.GetUpperBound(0); i++)
                Console.WriteLine("[{0}]:t{1}", i, arr.GetValue(i));
            Console.WriteLine();
            //笔画数 LCID:0x00020804
            CultureInfo StrokCi = new CultureInfo(133124);
            Thread.CurrentThread.CurrentCulture = StrokCi;
            Array.Sort(arr);
            Console.WriteLine("按笔划数排序:");
            for (int i = arr.GetLowerBound(0); i <= arr.GetUpperBound(0); i++)
                Console.WriteLine("[{0}]:t{1}", i, arr.GetValue(i));
            Console.WriteLine();
            //zh-cn (拼音:简中)
            Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-cn");
            Array.Sort(arr);
            Console.WriteLine("zh-cn:");
            for (int i = arr.GetLowerBound(0); i <= arr.GetUpperBound(0); i++)
                Console.WriteLine("[{0}]:t{1}", i, arr.GetValue(i));
            Console.WriteLine();
            //zh-tw (笔划数:繁中)
            Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-tw");
            Array.Sort(arr);
            Console.WriteLine("zh-tw:");
            for (int i = arr.GetLowerBound(0); i <= arr.GetUpperBound(0); i++)
                Console.WriteLine("[{0}]:t{1}", i, arr.GetValue(i));
            Console.ReadKey();
        }
    }

C#二叉树

public class TreeNode
    {
        private T data;
        private TreeNode leftNode;
        private TreeNode rightNode;
        public TreeNode(T nodeValue)
        {
            data = nodeValue;
            leftNode = null;
            rightNode = null;
        }
        //数据
        public T Data
        {
            get { return data; }
            set { data = value; }
        }
        //左子树
        public TreeNode LeftNode
        {
            get { return leftNode; }
            set { leftNode = value; }
        }
        //右子树
        public TreeNode RightNode
        {
            get { return rightNode; }
            set { rightNode = value; }
        }
        /// 
        /// 前序遍历:先跟节点然后左子树,右子树
        /// 
        /// 
        public void PreOrderTree(TreeNode root)
        {
            if (root != null)
            {
                Console.Write(root.Data);
                PreOrderTree(root.LeftNode);
                PreOrderTree(root.RightNode);
            }
        }
        /// 
        /// 中序遍历:左子树,根节点,右子树可以实现顺序输出
        /// 
        /// 
        public void InOrderTree(TreeNode root)
        {
            if (root != null)
            {
                InOrderTree(root.LeftNode);
                Console.Write(root.Data);
                InOrderTree(root.RightNode);
            }
        }
        /// 
        /// 深度
        /// 
        /// 
        /// 
        public int GetTreeDepth(TreeNode tree)
        {
            if (tree == null)
                return 0;
            int leftDepth = GetTreeDepth(tree.LeftNode);
            int rightDepth = GetTreeDepth(tree.RightNode);
            return leftDepth > rightDepth ? (leftDepth + 1) : (rightDepth + 1);
        }
    }

C#反转链表

public class ReverseLinkedList
    {
        void main()
        {
            Node list = InitList();
            Console.WriteLine(list);
            list = list.ReverseList(list);
            Console.WriteLine(list);
        }
        public Node InitList()
        {
            Node head = new Node();
            head.Next = null;
            head.Data = -1;
            Node q, p;
            p = head;
            for (int i = 1; i <= 10; i++)
            {
                q = new Node();
                q.Data = i;
                q.Next = null;
                p.Next = q;
                p = q;
            }
            return head;
        }
    }
    public class Node
    {
        private T data;
        private Node next;
        public T Data
        {
            get { return data; }
            set { this.data = value; }
        }
        public Node Next
        {
            get { return next; }
            set { next = value; }
        }
        public Node ReverseList(Node head)
        {
            if (head.Next == null || head.Next.Next == null)
            {
                return head;   /*链表为空或只有一个元素则直接返回*/
            }
            Node t = null,
                     p = head.Next,
                     q = head.Next.Next;
            while (q != null)
            {
                t = q.Next;
                q.Next = p;
                p = q;
                q = t;
            }
            /*此时q指向原始链表最后一个元素,也是逆转后的链表的表头元素*/
            head.Next.Next = null;  /*设置链表尾*/
            head.Next = p;           /*调整链表头*/
            return head;
        }
        public override string ToString()
        {
            string result = string.Empty ;
            Node p = this.Next;
            while (p != null)
            {
                result += string.Format("{0}t", p.Data);
                p = p.Next;
            }
            return result;
        }
    }