如何在C#中创建包含各种类型属性的类

时间:2010-10-11 09:51:26

标签: c# generics inheritance

我正在尝试创建一个类来表示SQL中列的值。这是我想达到的最终目标:

public string GenerateInsertSql()
{
  StringBuilder insertSql = new StringBuilder();
  insertSql.Append("INSERT INTO " + SchemaName + "." + TableName + "\n");
  insertSql.Append("(\n");
  int counter = 0;
  foreach (ColumnValue columnValue in _insertValues)
  {
    if (counter > 0) insertSql.Append(",");
    counter++;
    insertSql.Append(columnValue.ColumnName).Append("\n");
  }
  insertSql.Append(")\n");
  insertSql.Append("VALUES\n");
  insertSql.Append("(\n");
  counter = 0;
  foreach (ColumnValue columnValue in _insertValues)
  {
    if (counter > 0) insertSql.Append(",");
    counter++;
    insertSql.Append(columnValue.SqlValue).Append("\n");
  }
  insertSql.Append(")\n");
}

所以这个类是上面提到的ColumnValue类。 ColumnValue类需要一个Value属性,可能是任何基本的.NET类型(int,string等)。该类还有一个属性SqlValue,它提供了Value属性的字符串表示形式,我可以在生成的SQL语句中使用该属性。因此,如果Value是一个int,那么SqlValue只给出Value.ToString(),而如果Value是一个字符串,SqlValue需要检查字符串是否为空命令返回'NULL'或Value属性本身。

最初我尝试将Value作为对象,SqlValue在switch语句中测试Value的类型:

public string SqlValue
{
  get
  {
    switch (Value.GetType())
    {
      ...
    }
  }
}

然后我得到'预期的积分类型的价值'。所以我无法检查对象的类型。

接下来我尝试了泛型。我使用ColumnValue属性将ColumnValue<T>类更改为Value,如下所示:

public T Value { get; set; }

然后,在SqlValue属性中,再次检查T的类型,但我也不允许这样做。

有没有办法在C#中实现这一点,而不是简单地创建单独的类来处理每种可能的列类型?

3 个答案:

答案 0 :(得分:0)

switch关键字只能采用整数(正确地说,整数类型(参见here))。但是你总是可以使用“if”语句。例如,

var t = value.GetType();
if (t == typeof(string))
{
   ..
}
else if (t == typeof(int))
{
}
else if ...

您还可以使用“是”关键字。例如,

if (value is string) 
{
  ...
}
else if (value is int)
{
  ...
}
else if ...

“是”运算符也将在继承层次结构中进行检查,但我不认为您的使用情况会如此。

最后,我希望您要执行的任何SqlValue实现都将处理转义(例如 - 字符串值中的引号)并防止sql注入攻击。您可以考虑生成参数化查询insetad(即为查询中的每一列添加参数,然后将实际值作为参数值传递 - 因此您根本不需要SqlValue属性。)

答案 1 :(得分:0)

如果使用参数,则可以让SqlValue返回一个对象。

您的示例需要在字符串周围添加引号并处理文化问题(格式化double,date)。

答案 2 :(得分:0)

您还可以使用Type.GetTypeCode(Value.GetType()),它将把它变成枚举TypeCode,它具有从数据库中检索的所有原始值,尤其是枚举。除了作为对象出现的Guid之外,你可以在对象块中处理它。