关于C#中使用SQLite自适应Any CPU程序的说明

在C#中如果要使程序自适应32位和64位系统,只需要将项目的“目标平台”设置为“Any CPU”就行了,但是如果程序中使用了SQLite组件,则需要对该组件额外进行一些简单的设置:

一、下载System.Data.SQLite组件:
从官网(http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki)中下载对应.NET版本的System.Data.SQLite二进制包,由于要自适应32位和64位系统,我们需要分别下载32位和64位的非静态连接二进制包:
csharp-sqlite-any-cpu-1

二、引用System.Data.SQLite.dll:
在C#程序中引用组件“System.Data.SQLite.dll”,比对下载的这两个二进制包,我们会发现除了SQLite.Interop组件外,其他文件是一样的,所以我们可以自由选择32位或64位的System.Data.SQLite.dll文件:
csharp-sqlite-any-cpu-2

三、引用SQLite.Interop.dll:
在程序生成目录里新建x86和x64两个子文件夹,分别将下载的对应平台的SQLite.Interop.dll复制到x86和x64文件夹中,由System.Data.SQLite.dll根据系统类型自动调用。为了方便管理,我们可以在项目中创建这两个文件夹,并设置SQLite.Interop.dll文件的属性为“如果较新则复制”,生成操作为“无”,从而使程序在生成的时候自动复制SQLite.Interop.dll文件:
csharp-sqlite-any-cpu-3

四、编译生成程序:
完成以上步骤后对程序进行编译生成,程序中使用的SQLite组件就能自适应32位和64位系统了。

关于C#中反射调用泛型方法的说明

在C#中通过反射的方式调用定义为泛型的方法时,我们需要先根据方法名称获取方法描写对象“MethodInfo”,然后通过
该对象的“MakeGenericMethod”方法构造出对应实际泛型类型的泛型方法,从而才能被我们使用:

// 定义的泛型方法结构
public void Test<T>();

// 获取当前类型
Type type = this.GetType();
// 获取Test的方法对象
MethodInfo methodInfo = type.GetMethod("Test");
// 定义泛型类型
Type genericType = typeof(int);
// 获取对应泛型类型的泛型方法
methodInfo = methodInfo.MakeGenericMethod(genericType);
// 反射调用泛型方法
methodInfo.Invoke(this, null);

关于C#中获取可空泛型类型Nullable中的基础类型的说明

在C#中可以使用在值类型后加问号(如“int?”)的方式定义可空的类型,该定义出来的类型实际是一个“Nullable<T>”的泛型类型。但是在对该类型数据进行强制转换等操作时会因为数据类型不匹配等原因无法转换,这个时候我们就需要取出该可空类型的实际基础类型:

// 定义可空泛型值类型
Type type = typeof(int?);
// 判断目标type是否是可空的泛型类型
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
    // 取出可空泛型类型中的基础类型
    type = Nullable.GetUnderlyingType(type);
}
// 返回基础值类型:int
return type;

关于C#中对象和字典间相互转换的说明

一、对象转换为字典:

/// <summary>
/// 转换对象为字典
/// </summary>
/// <param name="obj">要转换的对象</param>
/// <param name="members">需要转换的成员</param>
/// <param name="ignoreMembers">忽略转换的成员</param>
/// <returns>返回字典</returns>
public virtual Dictionary<string, object> ConvertDictionary(object obj, string[] members, string[] ignoreMembers)
{
    // 创建目标字典
    Dictionary<string, object> dictionary = new Dictionary<string, object>();
    // 获取对象类型
    Type type = obj.GetType();
    // 获取成员字段
    FieldInfo[] fieldInfos = type.GetFields();
    // 遍历成员字段,添加要转换的成员字段到字典中
    foreach (FieldInfo fieldInfo in fieldInfos)
    {
        // 获取当前字段名
        string name = fieldInfo.Name;
        // 判断当前字段是否需要转换
        if ((members == null || members.Length <= 0 || members.Contains("*") || members.Contains(name)) && (ignoreMembers == null || ignoreMembers.Length <= 0 || (!ignoreMembers.Contains("*") && !ignoreMembers.Contains(name))))
        {
            // 判断当前字段是否是公开的
            if (fieldInfo.IsPublic)
            {
                // 判断当前字段是否是静态的
                if (fieldInfo.IsStatic)
                {
                    // 获取成员字段的静态值并设置到字典中
                    dictionary[name] = fieldInfo.GetValue(null);
                }
                else
                {
                    // 获取成员字段的实例值并设置到字典中
                    dictionary[name] = fieldInfo.GetValue(obj);
                }
            }
        }
    }
    // 获取成员属性
    PropertyInfo[] propertyInfos = type.GetProperties();
    // 遍历成员属性,添加要转换的成员属性到字典中
    foreach (PropertyInfo propertyInfo in propertyInfos)
    {
        // 获取当前属性名
        string name = propertyInfo.Name;
        // 判断当前属性是否需要转换
        if ((members == null || members.Length <= 0 || members.Contains("*") || members.Contains(name)) && (ignoreMembers == null || ignoreMembers.Length <= 0 || (!ignoreMembers.Contains("*") && !ignoreMembers.Contains(name))))
        {
            // 判断当前属性是否可读的并且是简单的类型
            if (propertyInfo.CanRead)
            {
                // 获取当前属性的GET访问器
                MethodInfo methodInfo = propertyInfo.GetGetMethod();
                // 判断当前属性的GET访问器是否是公开的
                if (methodInfo.IsPublic)
                {
                    // 判断当前属性的GET访问器是否是静态的
                    if (methodInfo.IsStatic)
                    {
                        // 获取成员属性的静态值并设置到字典中
                        dictionary[name] = propertyInfo.GetValue(null, null);
                    }
                    else
                    {
                        // 获取成员属性的实例值并设置到字典中
                        dictionary[name] = propertyInfo.GetValue(obj, null);
                    }
                }
            }
        }
    }
    // 返回字典
    return dictionary;
}

二、字典转换为对象:

/// <summary>
/// 转换字典为对象
/// </summary>
/// <param name="type">对象类型</param>
/// <param name="dictionary">要转换的字典</param>
/// <param name="members">需要转换的成员</param>
/// <param name="ignoreMembers">忽略转换的成员</param>
/// <returns>返回对象</returns>
public virtual object ConvertDictionary(Type type, Dictionary<string, object> dictionary, string[] members, string[] ignoreMembers)
{
    // 创建目标对象
    object obj = Activator.CreateInstance(type);
    // 遍历字典,添加要转换的数据到对象成员中
    foreach (KeyValuePair<string, object> item in dictionary)
    {
        // 获取成员名称
        string name = item.Key;
        // 判断当前成员是否需要转换
        if ((members == null || members.Length <= 0 || members.Contains("*") || members.Contains(name)) && (ignoreMembers == null || ignoreMembers.Length <= 0 || (!ignoreMembers.Contains("*") && !ignoreMembers.Contains(name))))
        {
            // 获取当前成员名称对应的数据
            object value = item.Value;
            // 根据当前成员名称获取成员属性
            PropertyInfo propertyInfo = type.GetProperty(name);
            // 判断是否有对应名称的成员属性
            if (propertyInfo == null)
            {
                // 根据当前列名获取成员字段
                FieldInfo fieldInfo = type.GetField(name);
                // 判断成员字段是否存在并且是否是公开可写的
                if (fieldInfo != null && fieldInfo.IsPublic && !fieldInfo.IsLiteral && !fieldInfo.IsInitOnly)
                {
                    // 根据成员字段类型转换数据类型
                    value = this.ConvertType(value, fieldInfo.FieldType);
                    // 判断数据转换是否成功
                    if (value != null)
                    {
                        // 判断成员字段是否是静态的
                        if (fieldInfo.IsStatic)
                        {
                            // 设置成员字段的静态值
                            fieldInfo.SetValue(null, value);
                        }
                        else
                        {
                            // 设置成员字段的实例值
                            fieldInfo.SetValue(obj, value);
                        }
                    }
                }
            }
            else
            {
                // 判断成员属性是否可写
                if (propertyInfo.CanWrite)
                {
                    // 获取成员属性的SET访问器
                    MethodInfo methodInfo = propertyInfo.GetSetMethod();
                    // 判断成员属性的SET访问器是否是公开的
                    if (methodInfo.IsPublic)
                    {
                        // 根据成员属性类型转换数据类型
                        value = this.ConvertType(value, propertyInfo.PropertyType);
                        // 判断数据转换是否成功
                        if (value != null)
                        {
                            // 判断成员属性的SET访问器是否是静态的
                            if (methodInfo.IsStatic)
                            {
                                // 设置成员属性的静态值
                                propertyInfo.SetValue(null, value, null);
                            }
                            else
                            {
                                // 设置成员属性的实例值
                                propertyInfo.SetValue(obj, value, null);
                            }
                        }
                    }
                }
            }
        }
    }
    // 返回目标对象
    return obj;
}

关于C#中Array和DataTable间相互转换的说明

一、将Array转换为DataTable:

/// <summary>
/// 转换对象数组为数据表
/// </summary>
/// <param name="objs">对象数组</param>
/// <param name="members">需要转换的成员</param>
/// <param name="ignoreMembers">忽略转换的成员</param>
/// <returns>返回数据表</returns>
public virtual DataTable ConvertTable(object[] objs, string[] members, string[] ignoreMembers)
{
    // 创建目标数据表
    DataTable dataTable = new DataTable();
    // 获取对象数组元素类型
    Type type = objs.GetType().GetElementType();
    // 创建要转换的对象成员字典
    Dictionary<string, MemberInfo> memberInfos = new Dictionary<string, MemberInfo>();
    // 获取成员字段
    FieldInfo[] fieldInfos = type.GetFields();
    // 遍历成员字段,添加要转换的成员字段到字典中
    foreach (FieldInfo fieldInfo in fieldInfos)
    {
        // 获取当前字段名
        string name = fieldInfo.Name;
        // 判断当前字段是否需要转换
        if ((members == null || members.Length <= 0 || members.Contains("*") || members.Contains(name)) && (ignoreMembers == null || ignoreMembers.Length <= 0 || (!ignoreMembers.Contains("*") && !ignoreMembers.Contains(name))))
        {
            // 判断当前字段是否是公开的
            if (fieldInfo.IsPublic)
            {
                // 添加要转换的成员字段
                memberInfos[name] = fieldInfo;
            }
        }
    }
    // 获取成员属性
    PropertyInfo[] propertyInfos = type.GetProperties();
    // 遍历成员属性,添加要转换的成员属性到字典中
    foreach (PropertyInfo propertyInfo in propertyInfos)
    {
        // 获取当前属性名
        string name = propertyInfo.Name;
        // 判断当前属性是否需要转换
        if ((members == null || members.Length <= 0 || members.Contains("*") || members.Contains(name)) && (ignoreMembers == null || ignoreMembers.Length <= 0 || (!ignoreMembers.Contains("*") && !ignoreMembers.Contains(name))))
        {
            // 判断当前属性是否可读
            if (propertyInfo.CanRead)
            {
                // 获取当前属性的GET访问器
                MethodInfo methodInfo = propertyInfo.GetGetMethod();
                // 判断当前属性的GET访问器是否是公开的
                if (methodInfo.IsPublic)
                {
                    // 添加要转换的成员属性
                    memberInfos[name] = propertyInfo;
                }
            }
        }
    }
    // 遍历要转换的对象成员字典,添加数据列
    foreach (KeyValuePair<string, MemberInfo> item in memberInfos)
    {
        // 添加数据列
        DataColumn dataColumn = dataTable.Columns.Add(item.Key);
        // 定义数据列数据类型
        Type dataType = typeof(string);
        // 获取对象成员
        MemberInfo membeInfo = item.Value;
        // 判断对象成员是否是属性
        if (membeInfo is PropertyInfo)
        {
            // 获取成员属性
            PropertyInfo propertyInfo = membeInfo as PropertyInfo;
            // 设置数据列类型
            dataType = propertyInfo.PropertyType;
        }
        else
        {
            // 获取成员字段
            FieldInfo fieldInfo = membeInfo as FieldInfo;
            // 设置数据列类型
            dataType = fieldInfo.FieldType;
        }
        // 判断数据类型是否是可空的泛型值类型
        if (dataType.IsGenericType && dataType.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            // 取出可空泛型值类型中的基础值类型
            dataType = Nullable.GetUnderlyingType(dataType);
        }
        // 设置数据列数据类型
        dataColumn.DataType = dataType;
    }
    // 遍历对象数组,转换对象为数据行
    foreach (object obj in objs)
    {
        // 创建数据行数据链表
        List<object> values = new List<object>();
        // 遍历要转换的对象成员字典,转换成员数据
        foreach (KeyValuePair<string, MemberInfo> item in memberInfos)
        {
            // 定义成员数据
            object value = null;
            // 获取对象成员
            MemberInfo membeInfo = item.Value;
            // 判断对象成员是否是属性
            if (membeInfo is PropertyInfo)
            {
                // 获取成员属性
                PropertyInfo propertyInfo = membeInfo as PropertyInfo;
                // 获取当前成员属性的GET访问器
                MethodInfo methodInfo = propertyInfo.GetGetMethod();
                // 判断当前成员属性的GET访问器是否是静态的
                if (methodInfo.IsStatic)
                {
                    // 获取成员属性的静态值
                    value = propertyInfo.GetValue(null, null);
                }
                else
                {
                    // 获取成员属性的实例值
                    value = propertyInfo.GetValue(obj, null);
                }
            }
            else
            {
                // 获取成员字段
                FieldInfo fieldInfo = membeInfo as FieldInfo;
                // 判断当前成员字段是否是静态的
                if (fieldInfo.IsStatic)
                {
                    // 获取成员字段的静态值
                    value = fieldInfo.GetValue(null);
                }
                else
                {
                    // 获取成员字段的实例值
                    value = fieldInfo.GetValue(obj);
                }
            }
            // 添加成员数据到数据行数据链表中
            values.Add(value);
        }
        // 添加数据行
        dataTable.Rows.Add(values.ToArray());
    }
    // 返回数据表
    return dataTable;
}

二、将DataTable转换为Array:

/// <summary>
/// 转换数据表为对象数组
/// </summary>
/// <param name="type">对象类型</param>
/// <param name="dataTable">数据表</param>
/// <param name="members">需要转换的成员</param>
/// <param name="ignoreMembers">忽略转换的成员</param>
/// <returns>返回对象数组</returns>
public virtual object[] ConvertTable(Type type, DataTable dataTable, string[] members, string[] ignoreMembers)
{
    // 创建目标对象数组
    object[] objs = Array.CreateInstance(type, dataTable.Rows.Count) as object[];
    // 创建要转换的对象成员字典
    Dictionary<string, MemberInfo> memberInfos = new Dictionary<string, MemberInfo>();
    // 遍历数据表中所有列,添加要转换的对象成员到字典中
    foreach (DataColumn dataColumn in dataTable.Columns)
    {
        // 获取列名
        string name = dataColumn.ColumnName;
        // 判断当前列是否需要转换
        if ((members == null || members.Length <= 0 || members.Contains("*") || members.Contains(name)) && (ignoreMembers == null || ignoreMembers.Length <= 0 || (!ignoreMembers.Contains("*") && !ignoreMembers.Contains(name))))
        {
            // 根据当前列名获取成员属性
            PropertyInfo propertyInfo = type.GetProperty(name);
            // 判断是否有对应名称的成员属性
            if (propertyInfo == null)
            {
                // 根据当前列名获取成员字段
                FieldInfo fieldInfo = type.GetField(name);
                // 判断成员字段是否存在并且是否是公开可写的
                if (fieldInfo != null && fieldInfo.IsPublic && !fieldInfo.IsLiteral && !fieldInfo.IsInitOnly)
                {
                    // 添加要转换的对象成员
                    memberInfos[name] = fieldInfo;
                }
            }
            else
            {
                // 判断成员属性是否可写
                if (propertyInfo.CanWrite)
                {
                    // 获取成员属性的SET访问器
                    MethodInfo methodInfo = propertyInfo.GetSetMethod();
                    // 判断成员属性的SET访问器是否是公开的
                    if (methodInfo.IsPublic)
                    {
                        // 添加要转换的对象成员
                        memberInfos[name] = propertyInfo;
                    }
                }
            }
        }
    }
    // 遍历转换数据表中的所有行
    for (int i = 0, length = dataTable.Rows.Count; i < length; i++)
    {
        // 获取对应索引的数据行
        DataRow dataRow = dataTable.Rows[i];
        // 根据对象类型创建目标对象
        object obj = Activator.CreateInstance(type);
        // 遍历要转换的对象成员字典,转换成员数据
        foreach (KeyValuePair<string, MemberInfo> item in memberInfos)
        {
            // 获取当前行对应当前列的数据
            object value = dataRow[item.Key];
            // 获取对象成员
            MemberInfo membeInfo = item.Value;
            // 判断对象成员是否是属性
            if (membeInfo is PropertyInfo)
            {
                // 获取成员属性
                PropertyInfo propertyInfo = membeInfo as PropertyInfo;
                // 根据成员属性类型转换数据类型
                value = this.ConvertType(value, propertyInfo.PropertyType);
                // 判断数据转换是否成功
                if (value != null)
                {
                    // 获取成员属性的SET访问器
                    MethodInfo methodInfo = propertyInfo.GetSetMethod();
                    // 判断成员属性的SET访问器是否是静态的
                    if (methodInfo.IsStatic)
                    {
                        // 设置成员属性的静态值
                        propertyInfo.SetValue(null, value, null);
                    }
                    else
                    {
                        // 设置成员属性的实例值
                        propertyInfo.SetValue(obj, value, null);
                    }
                }
            }
            else
            {
                // 获取成员字段
                FieldInfo fieldInfo = membeInfo as FieldInfo;
                // 根据成员字段类型转换数据类型
                value = this.ConvertType(value, fieldInfo.FieldType);
                // 判断数据转换是否成功
                if (value != null)
                {
                    // 判断成员字段是否是静态的
                    if (fieldInfo.IsStatic)
                    {
                        // 设置成员字段的静态值
                        fieldInfo.SetValue(null, value);
                    }
                    else
                    {
                        // 设置成员字段的实例值
                        fieldInfo.SetValue(obj, value);
                    }
                }
            }
        }
        // 设置目标对象到对象数组中
        objs[i] = obj;
    }
    // 返回目标对象数组
    return objs;
}