我想做的事情非常简单。我有一个类来处理名为clsSQLInterface
的数据库执行。该类包含一个名为bool isSQLSafe
的静态函数,如果发送执行的SQL被认为是危险的,它将返回false
。这是我有一点,我可以过滤掉任何恶意事件。
现在,我的程序的另一部分实际上需要能够执行UPDATE
,DELETE
等操作。所以我想我会继承clsSQLInterface
类并覆盖{{ 1}}函数总是返回isSQLSafe
。
这不是关于数据库安全性的问题btw!
好的,所以我这样做了......
true
最重要的课......
public class clsSQLInterface //Code not shown, just definitions
{
private static string connectionString(string sKey){...}
public static bool isSQLSafe(string sSQL){...}
public static DataTable executeSQLText(string sSQL, string sConnectionKey){...}
public static DataTable executeGenericQuery(clsGenericSQL query,string sDBKey){...}
}
确定。这种方法的问题是从public class clsSQLInterface_unsafe : clsSQLInterface
{
public clsSQLInterface_unsafe()
{
}
public new static bool isSQLSafe(string sSQL) //overriding the base method
{ return true; }
}
和isSQLSafe
方法中调用executeSQLText
。我希望这些方法做的是调用重写的executeGenericQuery
,它总是返回true。但是,他们没有。他们称之为基础实现。
我是否还必须覆盖调用isSQLSafe
的每个方法? 这似乎浪费了代码。
当我继承课程时,我实际上是在“复制”所有基本方法,它们应该表现得好像它们现在是isSQLSafe
的一部分?
答案 0 :(得分:6)
您无法覆盖静态方法。它们不是继承的,它们是类的方法,而不是类的实例。基类中的静态方法总是在同一个类中调用静态方法 只是让方法不是静态的和虚拟的,然后在派生类中覆盖它们应该可以解决你的问题。
编辑:new static
修饰符只是告诉编译器您打算隐藏基类的方法(尝试删除它并查看警告你得到),但它没有覆盖任何东西。
覆盖意味着函数的派生类版本取代了虚拟表中的基类版本。
虚拟表是与实例关联的方法的索引。没有实例,没有虚拟表,因此您无法覆盖静态方法。
P.S:看看这里对虚拟表的更好解释:http://en.wikipedia.org/wiki/Virtual_method_table
答案 1 :(得分:3)
问题来自static
修饰符。
您可以重新考虑重构您的代码,为什么不这样:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public abstract class BaseSqlInterface
{
protected abstract bool IsSafe(string instruction);
public void Execute(string sqlStatement)
{
if (IsSafe(sqlStatement))
{
// run the sql command
}
else
{
throw new Exception("You're evil");
}
}
}
public class SqlInterfaceSafe : BaseSqlInterface
{
public override bool IsSafe(string instruction)
{
return instruction.Contains("I'm not evil, I promise");
}
}
public class SqlInterfaceUnsafe : BaseSqlInterface
{
public override bool IsSafe(string instruction)
{
return true;
}
}
public static class SqlInterfaceFactory
{
public static BaseSqlInterface GetInstance()
{
// return the actual object using IOC, switch, ... whichever method you want
return DateTime.Now.Day % 2 == 0 ? (BaseSqlInterface)new SqlInterfaceSafe() : new SqlInterfaceUnsafe();
}
}
}