【问题标题】:Do I write these using statements inside or outside the class?我是在课内还是课外编写这些 using 语句?
【发布时间】:2023-04-03 03:55:01
【问题描述】:

我编写了一个类,其中包含对从我的数据库中提取的数据执行计算的不同方法。每个方法都从数据库中提取信息并对其执行计算,然后将其保存到类中的一个变量中,当我初始化类时可以访问该变量。我在下面有两种伪代码方法,我正在尝试找出以下内容:

  1. 如果每个方法都提取数据然后对其执行计算,我应该以哪种方式使用 using 语句?
  2. 我是否使用最有效的方式来存储数据?

这是我在初始化类时所做的

    public class Calculations
    {
    public string Symbol { get; set; }
    public string Market { get; set; }
    public List<decimal> stockPctReturns { get; set; }
    public List<decimal> marketPctReturns { get; set; }
    public enum returnType { Market, Stock };
    public decimal avgAnnualMarketGrowth { get; set; }
    public List<decimal> stockPctGains { get; set; }
    public List<decimal> stockPctLosses { get; set; }
    public List<decimal> positiveMoneyFlow { get; set; }
    public List<decimal> negativeMoneyFlow { get; set; }
    public decimal rsi { get; set; }
    public decimal mfi { get; set; }
    public decimal williamsR { get; set; }
    public decimal sma20 { get; set; }
    public decimal sma50 { get; set; }
    public decimal sma200 { get; set; }
    public const decimal riskFree10Yr = 2.58M;

    public Calculations(string symbol, string market)
    {
        // initialize everything in the class
        Symbol = symbol;
        Market = market;
    }
}

这样做:

public void fillPctReturns()
    {
        stockPctReturns = new List<decimal>();
        marketPctReturns = new List<decimal>();

        using (DailyGlobalDataTableAdapter dailyGlobalAdapter = new DailyGlobalDataTableAdapter())
        using (DailyAmexDataTableAdapter dailyAmexAdapter = new DailyAmexDataTableAdapter())
        using (DailyGlobalDataTable dailyGlobalTable = new DailyGlobalDataTable())
        using (DailyAmexDataDataTable dailyAmexTable = new DailyAmexDataDataTable())
        {
            dailyAmexAdapter.Fill(dailyAmexTable);
            dailyGlobalAdapter.Fill(dailyGlobalTable);
                    var amexQuery = from c in dailyGlobalTable.AsEnumerable()
                                    where c.Date >= DateTime.Now.Subtract(TimeSpan.FromDays(60))
                                    orderby c.Date descending
                                    join d in dailyAmexTable.AsEnumerable() on c.Date equals d.Date
                                    select new StockMarketCompare { stockClose = d.AdjustedClose, marketClose = c.AdjustedClose };

                    List<StockMarketCompare> amexResult = amexQuery.ToList();
// perform calculations here and save to stockPctReturns and marketPctReturns
         }
  }

或者我应该这样做:

using (DailyGlobalDataTableAdapter dailyGlobalAdapter = new DailyGlobalDataTableAdapter())
        using (DailyAmexDataTableAdapter dailyAmexAdapter = new DailyAmexDataTableAdapter())
        {
            Calculations calc = new Calculations();
            calc.Symbol = "GOOG";
            calc.Market = "nyse";
            dailyAmexAdapter.Fill(calc.dailyAmexTable);
            dailyGlobalAdapter.Fill(calc.dailyGlobalTable);
            calc.fillPctReturns();
        }

// 这个例子在数据表的计算类中有公共属性,你可以看到我像上面那样设置它们

希望你能说出我想要做什么。

【问题讨论】:

    标签: c# sql strongly-typed-dataset


    【解决方案1】:

    看起来您展示的第二种方法现在允许您将 dailyAmexTabledailyGlobalTable 包装在 using 块中,因此,如果它们各自的类实现 IDisposable(我假设它们基于您的其他代码),那么我更喜欢第一种方法。这允许您将所有 IDisposable 实例包装在 using 块中,您应该这样做。

    使用块的主要问题是,您通常希望在不再需要它们时立即关闭它们以释放资源。因此,您应该尝试 using 块之外进行计算,除非您需要在执行计算后将某些内容保存回数据库。所以它看起来像这样:

    public void fillPctReturns()
    {
        stockPctReturns = new List<decimal>();
        marketPctReturns = new List<decimal>();
    
        // Declare amexResult here so it is accessible outside the using block
        List<StockMarketCompare> amexResult;
    
        using (DailyGlobalDataTableAdapter dailyGlobalAdapter = new DailyGlobalDataTableAdapter())
        using (DailyAmexDataTableAdapter dailyAmexAdapter = new DailyAmexDataTableAdapter())
        using (DailyGlobalDataTable dailyGlobalTable = new DailyGlobalDataTable())
        using (DailyAmexDataDataTable dailyAmexTable = new DailyAmexDataDataTable())
        {
            dailyAmexAdapter.Fill(dailyAmexTable);
            dailyGlobalAdapter.Fill(dailyGlobalTable);
            var amexQuery = from c in dailyGlobalTable.AsEnumerable()
                            where c.Date >= DateTime.Now.Subtract(TimeSpan.FromDays(60))
                            orderby c.Date descending
                            join d in dailyAmexTable.AsEnumerable() on c.Date equals d.Date
                            select new StockMarketCompare { stockClose = d.AdjustedClose, marketClose = c.AdjustedClose };
    
            amexResult = amexQuery.ToList();
    
         }
         // perform calculations here and save to stockPctReturns and marketPctReturns
    }
    

    编辑:

    现在我更清楚地看到了你在做什么,我建议在课堂之外使用 using 块。主要原因是确保您的代码是松散耦合,在这种情况下意味着数据访问代码与业务逻辑是分开的(又名计算)代码。一种方法是在计算类之外运行查询,并将查询结果传递给计算类中的属性。例如:

    public class Calculations
    {
        public List<StockMarketCompare> Data { get; set; }
        // (Other properties and methods omitted.)
    }
    

    然后在你的调用函数中:

    var calc = new Calculations();
    using (DailyGlobalDataTableAdapter dailyGlobalAdapter = new DailyGlobalDataTableAdapter())
    using (DailyAmexDataTableAdapter dailyAmexAdapter = new DailyAmexDataTableAdapter())
    using (DailyGlobalDataTable dailyGlobalTable = new DailyGlobalDataTable())
    using (DailyAmexDataDataTable dailyAmexTable = new DailyAmexDataDataTable())
    {
        dailyAmexAdapter.Fill(dailyAmexTable);
        dailyGlobalAdapter.Fill(dailyGlobalTable);
        var amexQuery = from c in dailyGlobalTable.AsEnumerable()
                        where c.Date >= DateTime.Now.Subtract(TimeSpan.FromDays(60))
                        orderby c.Date descending
                        join d in dailyAmexTable.AsEnumerable() on c.Date equals d.Date
                        select new StockMarketCompare { stockClose = d.AdjustedClose, marketClose = c.AdjustedClose };
    
        calc.Data = amexQuery.ToList();
        calc.fillPctReturns();
        // Run any other calculations here.
        // Save data to DB here.
    }
    

    【讨论】:

    • 所以我应该在每种方法中都这样做吗?我刚刚被告知你永远不应该重复相同的代码,这就是我想出第一种方法的原因。另外,如果我将它从数据库中提取的结果保存在 using 语句中,如果我在 using 语句之外访问它,我仍然能够看到该数据吗?
    • 你是对的——如果可能的话,你不应该重复相同的代码。根据您所做的事情,您可能希望创建一个私有方法来为您获取数据,并从您的所有其他方法中调用该私有方法。
    • 回答您的另一个问题:是的,由于您在 using 块内调用 ToList(),因此可以在 using 块之外访问数据。
    • 我所做的一切与上面几乎相同,只是有更多的方法可以执行不同的计算。我打电话给班级并调用我需要的任何方法。
    • 好的。那么所有的计算方法都使用相同的数据吗?您会连续调用 2 种不同的计算方法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 2010-12-31
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    相关资源
    最近更新 更多