如何实现此C#类层次结构

时间:2011-02-02 10:02:45

标签: c# inheritance override class-design

我想做的事情非常简单。我有一个类来处理名为clsSQLInterface的数据库执行。该类包含一个名为bool isSQLSafe的静态函数,如果发送执行的SQL被认为是危险的,它将返回false。这是我有一点,我可以过滤掉任何恶意事件。

现在,我的程序的另一部分实际上需要能够执行UPDATEDELETE等操作。所以我想我会继承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的一部分?

2 个答案:

答案 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();
            }
        }
    }