如何实现这个 C# 类层次结构

发布于 2024-10-15 04:36:16 字数 1376 浏览 1 评论 0原文

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

现在,我的程序的另一部分实际上需要能够执行诸如 UPDATEDELETE 等操作。所以我想我应该继承 clsSQLInterface类并使用始终返回 true 的内容覆盖 isSQLSafe 函数。

顺便说一句,这不是关于数据库安全性的问题!

好吧,我这样做了......

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; }
}

好吧。这种方法的问题在于,从方法 executeSQLTextexecuteGenericQuery 中调用 isSQLSafe。我希望这些方法做的是调用重写的 isSQLSafe ,它总是返回 true。然而,他们没有。他们称之为基础实现。

我是否还必须重写每个调用 isSQLSafe 的方法? 这看起来像是浪费代码。

当然,当我继承该类时,我实际上是在“复制”所有基本方法,并且它们的行为应该就像它们现在是 clsSQLInterface_unsafe 的一部分一样?

What I want to do is really simple. I have a class which handles my database executions called clsSQLInterface. This class contains a static function called bool isSQLSafe which will return false if the SQL being sent for execution is considered dangerous. This is so I have one point where I can filter out any malicious goings on.

Now, another part of my program actually needs to be able to do things like UPDATE, DELETE etc. So I thought I would inherit the clsSQLInterface class and override the isSQLSafe function with something that always returns true.

This isn't a question about database secutrity btw!

Ok so I did this like this...

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){...}
}

And the overriding class..

public class clsSQLInterface_unsafe : clsSQLInterface
{
    public clsSQLInterface_unsafe()
    {   
    }

    public new static bool isSQLSafe(string sSQL) //overriding the base method
    { return true; }
}

Ok. The problem with this approach is that isSQLSafe is called from within the methods executeSQLText and executeGenericQuery. What I want these methods to do is call the overridden isSQLSafe which always returns true. However, they don't. They call the base implementation.

Do I also have to override every method which calls isSQLSafe? This seems like a waste of code.

Surely when I inherit the class I am effectively 'copying' all the base methods and they should behave as though they are now part of clsSQLInterface_unsafe?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨落□心尘 2024-10-22 04:36:16

您不能覆盖静态方法。它们不是继承的,它们是类的方法,而不是类的实例的方法。基类中的静态方法将始终调用同一类中的静态方法。
只需使方法不是静态和虚拟的,然后在派生类中重写它们就可以解决您的问题。

编辑new static修饰符只是告诉编译器您打算隐藏基类的方法(尝试删除它并查看警告),但它不会覆盖任何内容。

覆盖意味着该函数的派生类版本正在取代虚拟表中的基类版本。
虚拟表是与实例关联的方法的索引。没有实例,没有虚拟表,因此您无法覆盖静态方法。

PS:在这里查看什么是虚拟表的更好解释:http://en.wikipedia。 org/wiki/Virtual_method_table

You cannot override static methods. They are not inherited, they are methods of the class, not of an instance of the class. A static method in the base class will always call the static method in the same class.
Just making the methods not static and virtual, then overriding them in the derived class should solve your problem.

EDIT: the new static modifier just tells the compiler that you intend to hide the method of the base class (try to remove it and see the warning you get), but it does not override anything.

Overriding means that the derived class version of the function is taking the place of the base class version in the virtual table.
The virtual table is an index of the methods associated to an instance. No instance, no virtual table, therefore you cannot override a static method.

P.S: have a look at a better explaination of what is a virtual table here: http://en.wikipedia.org/wiki/Virtual_method_table

稍尽春風 2024-10-22 04:36:16

问题来自于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();
            }
        }
    }

The problems comes from the static modifier.

You may reconsider refactor your code using, why not, something like this :

    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();
            }
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文