2

我已经阅读了很多关于使用静态方法的相互矛盾的意见,这让我很头疼。考虑以下:

在我的大多数 CRUD 应用程序中,我使用 SqlDataHandler 类来处理一个类(或在某些情况下是一组类)与数据库的交互。见下文:

public abstract SqlDataHandler
{
    #region Properties
    protected static string ConnectionString { get; set; }
    #endregion

    #region Methods
    protected static DataTable GetDataTable(SqlCommand GetTableCommand)
    {
        ...
    }
    #endregion  
}

public AccountSqlDataHandler : SqlDataHandler
{
    #region Methods
    public static DataTable GetAccountHistory()
    {
        SqlCommand getAccountHistoryCommand;

        ...

        return AccountSqlDataHandler.GetDataTable(getAccountHistoryCommand);
    }
    #endregion

    #region Ctors
    static AccountSqlDataHandler()
    {
        AccountSqlDataHandler.ConnectionString = "Connection string for account database";
    }
    #endregion
}


public Account
{
    #region Properties
    public List<HistoryItem> AccountHistory
    {
        get
        {
            List<HistoryItem> accountHistory;

            accountHistory =         
                this.getItemsFromDataTable(AccountSqlDataHandler.GetAccountHistory());

        return accountHistory;
        }
    }
    #endregion
}

正如我所看到的,如果我使用成员方法,那么我必须每次都创建一个 AccountSqlDataHandler 实例,或者在 Account 类中创建一个 AccountSqlDataHandler 成员。我认为这样做没有任何优势,但从我所读到的内容来看,这是一个优势。在我盲目地改变我的方法之前,我想了解它是什么。

4

3 回答 3

3

如果方法不依赖于特定实例,则一个好的经验法则是使用静态方法。IE

public static int Add (x, y)
{
    return x + y;
}

如果您确实依赖于实例,则应该使用实例方法。

public int Add(x)
{  
    return this.y + x;
}

现在您的具体问题是也许您连接到多个数据库,或者您有多个连接字符串。

如果你这样做了,那么实例化你的 sql 数据处理程序就非常有意义。但如果你不这样做,那就没什么必要了。

于 2013-07-16T17:36:13.847 回答
2

没有。事实上,当您添加和使用第二个处理程序时,您会遇到一个不错的错误。

试试这个代码(希望你会注意到与你的ConnectionString财产的相似之处):

internal class Program
{
    private static void Main(string[] args)
    {
        var bravo = new Bravo();
        var charlie = new Charlie();

        Console.WriteLine(bravo.GetValue());
        Console.WriteLine(charlie.GetValue());

        Bravo.EchoValue();
        Charlie.EchoValue();
    }
}

public abstract class Alpha
{
    protected static string Value { get; set; }

    public abstract string GetValue();
}

public class Bravo : Alpha
{
    static Bravo()
    {
        Value = "bravo";
    }

    public override string GetValue()
    {
        return Value;
    }

    public static void EchoValue()
    {
        Console.WriteLine(Value);
    }
}

public class Charlie : Alpha
{
    static Charlie()
    {
        Value = "charlie";
    }

    public override string GetValue()
    {
        return Value;
    }

    public static void EchoValue()
    {
        Console.WriteLine(Value);
    }
}

输出:

查理
查理
查理
查理
按任意键继续 。. .

ConnectionString是有效共享状态并在静态构造函数中对其进行修改意味着最后一次静态构造函数调用将为整个应用程序设置状态(直到某些东西将其设置为它想要的状态,但是这必须是规则,然后静态构造函数是无意义)。这将不可避免地导致我的帐户查询为什么会命中订单数据库?问题(因为开发人员没有在每次使用之前明确设置连接字符串)以及杀死该应用程序在多数据库上下文中工作的任何机会。

于 2013-07-16T17:39:46.747 回答
1

一般来说static,当该行为在逻辑上属于一个classtype而不是它的实例和静态数据时,该数据在所有实例之间共享时应该是某种东西。在您的情况下,您似乎需要Singleton为每个数据库创建一个。看看那个模式。很多时候,我看到单例被实现为不正确的静态类/方法。

.NET 中的另一件事是,静态方法(应该)是线程安全的,但实例方法不是。在实现静态方法时,您必须注意此准则。

于 2013-07-16T17:53:42.323 回答