如何将包含某些属性的custom-class类型的未知对象列表传递给方法?

B. *_*eff 1 c# methods list instantiation propertyinfo

我正在创建一个databasehelper类,其中包含访问SQLCE数据库的方法.我想使用相同的方法使用包含与不同表中的字段匹配的属性的不同类来读取行.要使用的类是在运行时确定的,我想将包含类中对象的列表传递给方法,并获取属性名并使用它们来读取数据库.会非常方便,因为我可以将它用于我的所有(SQLCE-)数据库.

(我更新了错误的代码以便在这里提供解决方案)

    #region ReadData
    ///----------------------------------------------------------------------
    /// <summary>
    /// Reads datarows from database and adds them to list.
    /// </summary>
    /// <param name="data">List containing objects with properties.</param>
    /// <param name="table">Table in database.</param>
    /// <param name="search">Substring of SQL-statement that follows 'WHERE'.</param>
    /// <param name="connect">Connectionstring.</param>
    /// <returns>true if successfull</returns>
    ///----------------------------------------------------------------------
    public static bool ReadData<T>(List<T> data, string table, string search, string connect) where T : class, new()
    {
        // Return if input id missing
        if (data == null || table == "" || connect == "") return false;

        // retrieve properties from Data 
        PropertyInfo[] propinf = typeof(T).GetProperties();

        // Create string with SQL-statement
        string fields = "";
        // retrieve fields from propinf
        foreach (PropertyInfo p in propinf)
        {
            fields += fields == "" ? p.Name : ", " + p.Name;
        }
        // create SQL SELECT statement with properties and search
        string sql = "SELECT " + fields + " FROM " + table;
        sql += search == "" ? "" : " WHERE " + search;

        // Instantiate and open database
        SqlCeConnection cn = new SqlCeConnection(connect);
        if (cn.State == ConnectionState.Closed)
        cn.Open();
        data.Clear();   // just in case
        try
        {
            SqlCeCommand cmd = new SqlCeCommand(sql, cn);
            cmd.CommandType = CommandType.Text;
            SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Scrollable);
            if (rs.HasRows)  // Only if database is not empty
            {
                while (rs.Read()) // read database
                {
                    // instantiate single item of list Data
                    var dataitem = new T();
                    int ordinal = 0;
                    foreach (PropertyInfo p in propinf)
                    {
                        // read database and
                        PropertyInfo singlepropinf = typeof(T).GetProperty(p.Name);
                        ordinal = rs.GetOrdinal(p.Name);
                        singlepropinf.SetValue(dataitem, rs.GetValue(ordinal), null); // fill data item
                    }
                    data.Add(dataitem);  // and add it to data.
                }
            }
            else
            {
                MessageBox.Show("No records matching '" + search + "'!");
                return false;
            }
        }
        catch (SqlCeException sqlexception)
        {
            MessageBox.Show(sqlexception.Message, "SQL-error.", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return false;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error.", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return false;
        }
        finally
        {
            cn.Close();
        }
        return true;
    }
    #endregion
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

1)如何通过未知类型的列表?我到目前为止找到的答案并没有帮助我解决这个问题.

2)如何实例化一个未知类型的对象(在编译时),以便将它添加到List而不会导致编译错误?

非常感谢!

Mar*_*ell 5

1:未知类型的列表可以是非泛型的IList,或者ArrayList,或者List<object>

2: Activator.CreateInstance(type)

或者,看看编写泛型方法,理想情况如下:

ReadData<T>(List<T> data, ...) where T : class, new()
Run Code Online (Sandbox Code Playgroud)

并用于new T()创建新项目,并typeof(T)谈论Type.使用通用方法,调用者通常隐式地提供T.请注意,ref您的示例中不需要.