C#工具:反射幫助類 泛型反射幫助類

来源:https://www.cnblogs.com/liuyuanjiao/archive/2019/03/29/10623361.html
-Advertisement-
Play Games

反射幫助類 using System; using System.Reflection; using System.Data; using System.Drawing; using System.Resources; using System.ComponentModel; using Syste ...


反射幫助類

using System;
using System.Reflection;
using System.Data;
using System.Drawing;
using System.Resources;
using System.ComponentModel;
using System.Text;
using System.IO;

namespace Core.Common
{
    /// <summary>
    /// 反射輔助類
    /// </summary>
    public static class ReflectHelper
    {
        #region 成員讀寫
        /// <summary>
        /// 通過數據行填充實體類型
        /// </summary>
        /// <param name="model">實體對象</param>
        /// <param name="dRow">數據行</param>
        public static void FillInstanceValue(object model, DataRow dRow)
        {
            Type type = model.GetType();
            for (int i = 0; i < dRow.Table.Columns.Count; i++)
            {
                PropertyInfo property = type.GetProperty(dRow.Table.Columns[i].ColumnName);
                if (property != null)
                {
                    property.SetValue(model, dRow[i], null);
                }
            }
        }

        /// <summary>
        /// 通過數據只讀器填充實體類型
        /// </summary>
        /// <param name="model">實體對象</param>
        /// <param name="dr">數據只讀器</param>
        public static void FillInstanceValue(object model, IDataReader dr)
        {
            Type type = model.GetType();
            for (int i = 0; i < dr.FieldCount; i++)
            {
                PropertyInfo property = type.GetProperty(dr.GetName(i));
                if (property != null)
                {
                    property.SetValue(model, dr[i], null);
                }
            }
        }

        /// <summary>
        /// 獲取實體相關屬性的值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public static object GetInstanceValue(object obj, string propertyName)
        {
            object objRet = null;
            if (!string.IsNullOrEmpty(propertyName))
            {
                PropertyDescriptor descriptor = TypeDescriptor.GetProperties(obj).Find(propertyName, true);
                if (descriptor != null)
                {
                    objRet = descriptor.GetValue(obj);
                }
            }
            return objRet;
        } 
        #endregion

        #region 方法調用
        /// <summary>
        /// 直接調用內部對象的方法/函數或獲取屬性(支持重載調用)
        /// </summary>
        /// <param name="refType">目標數據類型</param>
        /// <param name="funName">函數名稱,區分大小寫。</param>
        /// <param name="objInitial">如果調用屬性,則為相關對象的初始化數據,否則為Null。</param>
        /// <param name="funParams">函數參數信息</param>
        /// <returns>運行結果</returns>
        public static object InvokeMethodOrGetProperty(Type refType, string funName, object[] objInitial, params object[] funParams)
        {
            MemberInfo[] mis = refType.GetMember(funName);
            if (mis.Length < 1)
            {
                throw new InvalidProgramException(string.Concat("函數/方法 [", funName, "] 在指定類型(", refType.ToString(), ")中不存在!"));
            }
            else
            {
                MethodInfo targetMethod = null;
                StringBuilder pb = new StringBuilder();
                foreach (MemberInfo mi in mis)
                {
                    if (mi.MemberType != MemberTypes.Method)
                    {
                        if (mi.MemberType == MemberTypes.Property)
                        {
                            #region 調用屬性方法Get
                            targetMethod = ((PropertyInfo)mi).GetGetMethod();
                            break;
                            #endregion
                        }
                        else
                        {
                            throw new InvalidProgramException(string.Concat("[", funName, "] 不是有效的函數/屬性方法!"));
                        }
                    }
                    else
                    {
                        #region 檢查函數參數和數據類型 綁定正確的函數到目標調用
                        bool validParamsLen = false, validParamsType = false;

                        MethodInfo curMethod = (MethodInfo)mi;
                        ParameterInfo[] pis = curMethod.GetParameters();
                        if (pis.Length == funParams.Length)
                        {
                            validParamsLen = true;

                            pb = new StringBuilder();
                            bool paramFlag = true;
                            int paramIdx = 0;

                            #region 檢查數據類型 設置validParamsType是否有效
                            foreach (ParameterInfo pi in pis)
                            {
                                pb.AppendFormat("Parameter {0}: Type={1}, Name={2}\n", paramIdx, pi.ParameterType, pi.Name);

                                //不對Null和接受Object類型的參數檢查
                                if (funParams[paramIdx] != null && pi.ParameterType != typeof(object) &&
                                     (pi.ParameterType != funParams[paramIdx].GetType()))
                                {
                                    #region 檢查類型是否相容
                                    try
                                    {
                                        funParams[paramIdx] = Convert.ChangeType(funParams[paramIdx], pi.ParameterType);
                                    }
                                    catch (Exception)
                                    {
                                        paramFlag = false;
                                    }
                                    #endregion
                                    //break;
                                }
                                ++paramIdx;
                            }
                            #endregion

                            if (paramFlag == true)
                            {
                                validParamsType = true;
                            }
                            else
                            {
                                continue;
                            }

                            if (validParamsLen && validParamsType)
                            {
                                targetMethod = curMethod;
                                break;
                            }
                        }
                        #endregion
                    }
                }

                if (targetMethod != null)
                {
                    object objReturn = null;
                    #region 兼顧效率和相容重載函數調用
                    try
                    {
                        object objInstance = System.Activator.CreateInstance(refType, objInitial);
                        objReturn = targetMethod.Invoke(objInstance, BindingFlags.InvokeMethod, Type.DefaultBinder, funParams,
                            System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (Exception)
                    {
                        objReturn = refType.InvokeMember(funName, BindingFlags.InvokeMethod, Type.DefaultBinder, null, funParams);
                    }
                    #endregion
                    return objReturn;
                }
                else
                {
                    throw new InvalidProgramException(string.Concat("函數/方法 [", refType.ToString(), ".", funName,
                        "(args ...) ] 參數長度和數據類型不正確!\n 引用參數信息參考:\n",
                        pb.ToString()));
                }
            }

        }

        /// <summary>
        /// 調用相關實體類型的函數方法
        /// </summary>
        /// <param name="refType">實體類型</param>
        /// <param name="funName">函數名稱</param>
        /// <param name="funParams">函數參數列表</param>
        /// <returns>調用該函數之後的結果</returns>
        public static object InvokeFunction(Type refType, string funName, params object[] funParams)
        {
            return InvokeMethodOrGetProperty(refType, funName, null, funParams);
        } 
        #endregion

        #region 資源獲取
        /// <summary>
        /// 獲取程式集資源的點陣圖資源
        /// </summary>
        /// <param name="assemblyType">程式集中的某一對象類型</param>
        /// <param name="resourceHolder">資源的根名稱。例如,名為“MyResource.en-US.resources”的資源文件的根名稱為“MyResource”。</param>
        /// <param name="imageName">資源項名稱</param>
        public static Bitmap LoadBitmap(Type assemblyType, string resourceHolder, string imageName)
        {
            Assembly thisAssembly = Assembly.GetAssembly(assemblyType);
            ResourceManager rm = new ResourceManager(resourceHolder, thisAssembly);
            return (Bitmap)rm.GetObject(imageName);
        }

        /// <summary>
        ///  獲取程式集資源的文本資源
        /// </summary>
        /// <param name="assemblyType">程式集中的某一對象類型</param>
        /// <param name="resName">資源項名稱</param>
        /// <param name="resourceHolder">資源的根名稱。例如,名為“MyResource.en-US.resources”的資源文件的根名稱為“MyResource”。</param>
        public static string GetStringRes(Type assemblyType, string resName, string resourceHolder)
        {
            Assembly thisAssembly = Assembly.GetAssembly(assemblyType);
            ResourceManager rm = new ResourceManager(resourceHolder, thisAssembly);
            return rm.GetString(resName);
        }

        /// <summary>
        /// 獲取程式集嵌入資源的文本形式
        /// </summary>
        /// <param name="assemblyType">程式集中的某一對象類型</param>
        /// <param name="charset">字元集編碼</param>
        /// <param name="ResName">嵌入資源相對路徑</param>
        /// <returns>如沒找到該資源則返回空字元</returns>
        public static string GetManifestString(Type assemblyType, string charset, string ResName)
        {
            Assembly asm = Assembly.GetAssembly(assemblyType);
            Stream st = asm.GetManifestResourceStream(string.Concat(assemblyType.Namespace,
                ".", ResName.Replace("/", ".")));
            if (st == null) { return ""; }
            int iLen = (int)st.Length;
            byte[] bytes = new byte[iLen];
            st.Read(bytes, 0, iLen);
            return (bytes != null) ? Encoding.GetEncoding(charset).GetString(bytes) : "";
        } 
        #endregion

    }
}
反射幫類

 

泛型反射幫助類

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DAL
{
    public class Expdal
    {
        /// <summary>
        /// 顯示
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<T> GetTs<T>()where T:new()
        {
            //獲取Type對象,反射操作基本都是用Type進行的
            Type type = typeof(T);
            string sql = "select * from Expense";
            SqlDataReader dr = DBHelper.GetDataReader(sql);
            //獲取Type對象的所有公共屬性
            PropertyInfo[] info = type.GetProperties();
            List<T> modelList = new List<T>();
            //定義泛型對象
            T obj = default(T);
            while (dr.Read())
            {
                obj = new T();
                foreach (PropertyInfo item in info)
                {
                    item.SetValue(obj, dr[item.Name]);
                }
                modelList.Add(obj);
            }
            dr.Close();
            return modelList;
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="nodel"></param>
        /// <returns></returns>
        public static int AddExpense<T>(T nodel)where T : new()
        {
            Type type = typeof(T);
            string sql = string.Format("insert into {0} ", type.Name);
            string val = "";
            string link = "'";
            //獲取Type對象所有公共屬性
            PropertyInfo[] info = type.GetProperties();
            foreach (PropertyInfo item in info)
            {
                val += link + item.GetValue(nodel) + link+",";//定義欄位變數
            }
            val = val.Substring(0, val.Length - 1);
            val += ")";
            sql += "values(" + val.Remove(0,4);
            //調用執行方法
            return DBHelper.ExecuteNonQuery(sql);
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="nodel"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static int UpdateExpense<T>(T nodel,int id)where T:new()
        {
            Type type = typeof(T);
            string sql = string.Format("update {0} set  ", type.Name);

            PropertyInfo[] info = type.GetProperties();
            string link = "";
            foreach (PropertyInfo item in info)
            {
                object val = item.GetValue(nodel);
                if (val!=null)
                {
                    sql += link + item.Name + "='" + val + "' ";
                    link = ",  ";
                }
            }
            sql = sql.Remove(18, 12);
            sql += string.Format(" where EId=" + id);
            return DBHelper.ExecuteNonQuery(sql);
        }
        /// <summary>
        /// 刪除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public static int DeleteByEId<T>(int id)where T : new()
        {
            Type type = typeof(T);
            string sql = string.Format($"delete from {type.Name} where EId={id}");
            return DBHelper.ExecuteNonQuery(sql);
        }
    }
}
泛型反射幫助類

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原文鏈接:http://www.entityframeworktutorial.net/code-first/setup-entity-framework-code-first-environment.aspx 使用Code-First開發模式,你需要在項目中,通過Visual Studio安裝En ...
  • 最近開始在項目中使用easynetq,大概瞭解了下api,在網上看了下示例,結果沒有一個運行成功的,一個最簡單的發佈訂閱都沒有成功。我是直接運行起來別人的示例,不應該啊,後來一直分析一直分析,最後發現:消息沒有序列化!這還是其一,第二點,應該要先起來消息接收端,再起來消息發佈端。一開始就是簡單的: ...
  • 在涉及到金融業務這一塊的系統設計中,時常能夠遇到的情況是需要將阿拉伯數字的人民幣金額自動轉換為中文的大寫金額。現在互聯網上也有很多網站提供此類服務,只要你輸入人民幣的阿拉伯數字金額,輸入後自動給你轉換為中文大寫。C#實現將人民幣金額轉換為大寫的流程也不複雜,100行代碼都不需要,具體的實現參見以下詳 ...
  • 在Sqlserver資料庫中,一般我們查看資料庫的大小可以通過查找到資料庫文件來查看,但如果要查找數據表Table的大小的話,則不可通過此方法,在Sqlserver資料庫中,提供了相應的SQL語句來查詢資料庫DataBase的大小,以及庫中相應表的大小。 首先選中資料庫,可以通過手工選擇,也可通過在 ...
  • 在實際運行的伺服器環境中,我們自己網站中的資源一般不希望被外部網站引用,被外部網站引用IIS網站中的資源文件,一是會加重了伺服器的負擔,二是占用了你自己伺服器的外網帶寬資源,因此我們希望防止盜鏈這種情況。IIS伺服器提供了強大的設置功能,其中一項就包含防盜鏈。 通過我們遇到的盜鏈分為兩種,一種是圖片 ...
  • 圖片處理是C#程式開發中時常會涉及到的一個業務,除了圖像的上傳、保存以及下載等功能外,根據上傳的圖片生成一個縮略圖也是常見業務,在C#語言中,可以通過Image類提供的相關方法對圖片進行操作,如指定寬高對圖片進行縮放, 指定高寬裁減裁剪圖片、生成圖片水印等。 定義一個圖片處理工具類PicDeal,該 ...
  • Sqlserver在設置登錄賬戶信息的時候,有個覆選框信息會被預設勾上,即強制實施密碼策略,預設勾選上的還有強制密碼過期。如果勾上了這個強制密碼過期後,則你的賬戶密碼在一定時間登錄後會提示Sqlserver登錄密碼已過期請重新設置密碼,如果是正在運行中的網站的賬戶,則整個網站可能會因為登錄資料庫失敗 ...
  • 在C#的文件相關操作中,往已有的文件中追加相關內容信息也是常有的操作,例如我們在寫網站日誌文件的時候,很多時候是1天的日誌存放在一個txt文件中,此時就涉及到往原有文件中追加寫入文本內容信息,追加文本內容信息主要通過 File.AppendText方法以及 StreamWriter.Write方法來 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...