是否可以使用 class 的属性而不了解它(甚至是类型和名称)?

Is it possible to use class's properties not knowing anything about it (even a type and name)?

我想尽量不要用带有SQL语句的类似代码编写所有方法和classes,并遵循DRY原则。现在我需要访问未知 class.

的属性
public T Get(string pathToClass, string sqlStatement)
{
    SqlConnection connection = new SqlConnection();
    connection.ConnectionString = connectionString; //connectionString is field of class.
    connection.Open();

    SqlCommand command = new SqlCommand(sqlStatement);

    SqlDataReader reader = command.ExecuteReader();

    List<Type> types = new Reflect(pathToClass).GetTypes();   //Reflection is my class library
    List<string> names = new Reflect(pathToClass).GetNames(); //it only reads the classes and returns properties's names and types.

    object entity = new object(); //idk is it right or not, but seems it is.
    for(int i = 0; reader.Read(); i++)
    {
        entity.SomeProperty = types[i].Parse(reader[names[i]].ToString()); //There is a wrong point, where I'm confused
    }

    connection.Close();

    return (T)entity;
}

如果不使用 ORM,这里常用的方法是返回原始 DataRowIDataRecord 对象,使用静态工厂方法和 each/all 您的个人类型知道如何给定 IDataRecordDataRow 输入构造该类型的实例。

例如:

//Initial class might look like this:
public class Employee
{
    public string FirstName {get;set;}
    public string LastName {get;set;}
    public int ID {get;set;}
    public string Email {get;set;}

    public static Employee FromDataRow(DataRow row)
    {
        return new Employee
        {
            ID = row["ID"],
            FirstName = row["FirstName"],
            LastName = row["LastName"],
            Email = row["Email"]
        };
    }
}

//Data access might look like this:
public class DB
{
    private static string ConnectionString { get;} = "connection string here";
    public static IEnumerable<DataRow> FindEmployeeRecords(string LastName)
    {
        string sql = "SELECT ID, FirstName, LastName, Email FROM Employee WHERE LastName LIKE @LastName + '%'";
        using (var cn = new SqlConnection(ConnectionString))
        using (var cmd = new SqlCommand(sql, cn))
        using(var da = new SqlDataAdapter(cmd))
        {
            cmd.Parameters.Add("@LastName", SqlDbType.NVarChar, 80).Value = LastName;
            var result = new DataSet();
            da.Fill(result);
            return results.Tables[0].Rows;
        }
    }
}

// and then you could use it like this:
var employees = DB.FindEmpoyeeRecords("Smith").Select(Employee.FromDataRow);
foreach (var employee in employees) 
{
   //...
}
// or you could bind employees to a datasource

当然,您可以使用reflection将数据行字段映射到对象。您甚至可以将其中的一部分抽象为实用方法。但是,您仍然需要每种类型的工厂方法(只是代码少了一点),反射是 slow (就像,真的很慢),并且您失去了映射方式的灵活性如果您希望 class 字段与 table 列稍有不同,就会发生这种情况。

我们也可以reduce boilerplate code in the database layer。但是,这需要对函数式编程有更好的理解。