了解静态类和静态方法

时间:2015-08-25 13:46:14

标签: c#

假设我有一个这样的方法:

public class MyDataAccess
{
    public static StudentDataTable GetStudentRecords(int schoolID)
    {
        var ta = new StudentTableAdapter();
        using (ta.Connection = new SqlConnection(GetCS()))
        {
            var result = ta.GetStudentRecords(schoolID);
            return result;
        }
    }
}

如果使用控制台应用程序或任何其他方式一次访问此方法1,000次,是否有可能将一个学校的学生的记录返回到另一所学校?

e.g。

var records1 = GetStudentRecords(1);
.....
var records1000 = GetStudentRecords(1000);

records1变量是否有可能将schoolID = 1的记录与来自records1000的记录混合在一起,即使这些记录来自他们自己的主题?

如果我将这个类改为静态会发生什么呢?

此时我的理解

1)是的,我明白课程是什么

2)是的,我知道静态类不需要使用所需的实例

3)我知道应该有简单的静态代码,例如转换数据类型。

但我感到困惑的是:

当存在单个静态类并且有一百万个对象试图访问STACK中的同一个对象时会发生什么

尤其是当它是dataAccess类或访问activeDirectory个对象的类时。

我在程序员SE聊天室聊天。他们没有明确说出来,但我得到的印象是从不使用静态类来查询,例如sql,活动目录等。而且静态类应该仅限于简单的静态代码 - 不需要查询。

2 个答案:

答案 0 :(得分:5)

查看您给我们的代码,代码似乎是线程安全的。线程之间没有(内存中)数据共享。

我唯一关心的是数据库层 - 确保你使用正确的isolation level来避免脏读。

  

如果我将此类更改为静态也会发生什么。

关于GetStudentRecords?什么都没有。

这是线程不安全代码的经典示例。

public class MyDataAccess
{

    private static int _retrievalCount = 0;

    public static StudentDataTable GetStudentRecords(int schoolID)
    {
        _retrievalCount ++;

        // retrieve and return records;            
    }
}

字段_retrievalCount在线程间共享。操作++不是原子的。也就是说,它涉及三个步骤

  1. 检索存储在_retrievalCount
  2. 中的交互
  3. 向其添加1
  4. 并将结果存回_retrievalCount
  5. 如果两个线程同时执行此操作,并且这三个步骤是交错的,则可能会发生这种情况(假设_retrievalCount从0开始并且有2个线程正在运行):

    1. 主题A将_retrievalCount读为0
    2. 线程A将1加0,结果= 1
    3. 线程B将_retrievalCount读为0
    4. 线程B加1到0,结果= 1
    5. 主题A在_retrievalCount
    6. 中存储结果= 1
    7. 主题B在_retrievalCount
    8. 中存储result = 1

      预期输出为2,但实际输出为1.

答案 1 :(得分:5)

在C#中,“static”仅表示您可以直接从类定义中调用该方法,而不是针对该类的实例调用该方法。

将“类”视为对象的蓝图。创建对象的实例时,蓝图会告诉计算机如何创建它。但是,该类的某些方面不需要实际的对象实例,并且这些方面是通过“静态”方法提供的候选方法。

如果将方法声明更改为包含“static”,则会更改必须调用的方式。

public class Example
{   
    static void StaticMethod() {...};  // object instance *not* required
    void InstanceMethod() {...};       // object instance *is* required
}