C# 如何在C中创建包含各种类型属性的类#
我试图创建一个类来表示SQL中列的值。以下是我想要达到的最终目标: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 (
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#)中,开关只能采用整型,这是不正确的。。。关于引号和日期格式,你是对的。