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

C# 如何在C中创建包含各种类型属性的类#,c#,generics,inheritance,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 (

我试图创建一个类来表示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,以便返回“null”或
Value
属性本身

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

public string SqlValue
{
  get
  {
    switch (Value.GetType())
    {
      ...
    }
  }
}
但我得到了“期望的积分类型值”。所以我无法检查对象的类型

接下来我尝试了泛型。我将
ColumnValue
类更改为
ColumnValueT
,其
Value
属性如下:

public T Value { get; set; }
然后,在
SqlValue
属性中,对T类型进行另一次检查,但我也不允许这样做


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

switch关键字只能接受整数(正确地说,整数类型(请参阅))。但是你总是可以使用“如果”语句。比如说,

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 ...
您还可以使用“is”关键字。比如说,

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 ...
“is”操作符也将在继承层次结构中进行检查,但我认为在您的使用中不会出现这种情况


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

< P>如果您使用参数,可以让您的SqLValk返回一个对象。
您的示例需要在字符串周围添加引号,并处理区域性问题(double、date的格式)。

您还可以使用Type.GetTypeCode(Value.GetType()),这将把它转换为enum TypeCode,其中包含从数据库检索的所有基元值,尤其是枚举的基元值。除了Guid,它将作为对象出现,但您可以在对象块中处理它。

通过字符串连接创建SQL?我更担心Sql注入。谢谢你的警告,但这只是测试类生成的Sql。不涉及任何用户输入。还值得指出的是,上面的SQL可以快速修改为参数化值,从而完全保护它。开关只接受int不是真的。也许最好编辑一下。关于你的最后一段,这里需要对可空类型进行空检查-这就是SqlValue属性的用途。对不起,我误解了你的帖子。开关实际上只能接受“整型”。我以为是GetType()调用失败了,但事实上,问题在于它在交换机中的使用。谢谢。VinayC-Switch语句只能接受常量值-这包括字符串。(在c#)中,开关只能采用整型,这是不正确的。。。关于引号和日期格式,你是对的。