C#中的静态构造函数

49

我正在尝试使用如下所示的静态构造函数:

public static DataManager()
{
    LastInfoID = 1;
}

并且出现了以下错误:

静态构造函数上不允许使用访问修饰符

我想知道我的问题是什么。


5
在我看来,你应该询问“什么是访问修饰符?”请查阅你喜欢的C#语言书籍。现在错误信息变得非常易懂了。 - Hans Passant
2
access modifiers -> publicare not allowed -> 尝试将其删除。在我看来,C#编译消息非常清晰。如需查找未知术语,请使用Google:http://www.google.nl/search?q=C%23+access+modifiers - Dykam
5个回答

112

静态构造函数没有访问修饰符: 它只是:

static DataManager() // note no "public"
{
    LastInfoID = 1;
}

这是因为它从未被显式调用(除非通过反射) - 但是由运行时调用; 访问级别将没有意义。


静态构造函数的默认访问修饰符是什么?它也是public吗? - paraJdox1
我无法真正阅读生成的IL代码,它在哪个部分说明它是私有的?虽然“.class public auto ansi C”表示它是公共的。 - paraJdox1
@Hacki,classpublic(例如 public class C);静态构造函数是 private。你链接的视频是错误的,而且有两个错误:a) 因为它声称它们是公共的(但实际上不是),b) 因为它暗示这是“默认”的,这是没有意义的:这是唯一的选项。 - Marc Gravell
@Hacki 顺便提一下,表示静态构造函数是私有的代码如下:.method private hidebysig specialname rtspecialname static void .cctor () cil managed - 这定义了一个方法(.method),请注意它既是 static 又是 private;有一个运行时公认的约定(hidebysig specialname rtspecialname 意味着“查找特殊名称 - 它们不是偶然的”),即 .cctor 是一个特殊名称,用于定义“静态构造函数”(实际上,在 IL 中称为“类型初始化器” - 它可以包括不在 C# 静态构造函数中的代码,例如静态字段初始化器)。 - Marc Gravell
非常感谢您,@Marc Gravell先生,这非常有见地! - paraJdox1
显示剩余4条评论

5
问题在于您的类中的LastInfoID字段或属性未声明为静态(static),而您只能从静态构造函数中访问静态成员。同时,请从声明中删除public关键字:
static DataManager()
{
    LastInfoID = 1;
}

根据我所看到的问题,错误与“LastInfoID”毫无关系。但是问题可能已被编辑过。 - Fredrik Mörk
没有任何迹象表明ListInfoID不是静态的。 - Guffa
是的,我错了。这与“public”修饰符有关。对此抱歉。 - Darin Dimitrov

5

去掉public。静态构造函数的语法为:

class MyClass 
{
    static MyClass() 
    {
        // Static constructor
    }
}

5
为了给大家一个更清晰的答案,不需要示例,想一想为什么你需要从外部访问静态构造函数?静态类在应用程序执行时在内存中创建,这就是它们被声明为静态的原因。换句话说,你永远不需要显式地调用静态构造函数,如果你这样做了,比如通过反射(我不知道它是否能让你这样做),那么你就做错了。
当你创建一个类的新实例时,构造函数作为一种初始化所有内部变量并执行任何必要处理以使类按预期方式运行的方式存在。请注意,如果您没有指定构造函数,编译器将为您创建一个。因此,你仍然需要创建一个带有“()”的类,像这样:
     new MyClass();

由于您调用了默认构造函数(假设您没有定义无参构造函数),因此需要将非静态构造函数定义为公共的。换句话说,非静态构造函数必须定义为公共的原因是因为需要显式调用它。如果我的记忆没有出错,当尝试调用未定义为公共的(通过malloc)构造函数时,C#将无法编译代码。
静态类中的构造函数存在于“设置”目的上。例如,我可以有一个静态类,该类应该是我代码和我不断保存和读取数据的文件之间的桥梁。我可以定义一个构造函数,在对象创建时,确保文件存在,如果不存在则创建默认文件(在移植到其他服务器的Web系统中非常有用)。

1
using System;

public class Something
{
    //
    private static  DateTime _saticConstructorTime;
    private         DateTime _instanceConstructorTime;
    //
    public static DateTime SaticConstructorTime
    {
        set { _saticConstructorTime = value; }
        get { return _saticConstructorTime ; }
    }
    public DateTime InstanceConstructorTime
    {
        set { _instanceConstructorTime = value; }
        get { return _instanceConstructorTime; }
    }
    //Set value to static propriety 
    static Something()
    {
        SaticConstructorTime = DateTime.Now;
        Console.WriteLine("Static constructor has been executed at: {0}",
                        SaticConstructorTime.ToLongTimeString());
    }
    //The second constructor started alone at the next instances
    public Something(string s)
    {
        InstanceConstructorTime = DateTime.Now;
        Console.WriteLine("New instances: "+ s +"\n");
    }
    public void TimeDisplay(string s)
    {
        Console.WriteLine("Instance \""+ s + "\" has been created at: " + InstanceConstructorTime.ToLongTimeString());
        Console.WriteLine("Static constructor has been created at: " + SaticConstructorTime.ToLongTimeString() + "\n");
    }
}
//
class Client
{
    static void Main()
    {
        Something somethingA = new Something("somethingA");
        System.Threading.Thread.Sleep(2000);
        Something somethingB = new Something("somethingB");

        somethingA.TimeDisplay("somethingA");
        somethingB.TimeDisplay("somethingB");
        System.Console.ReadKey();
    }
}
/* output :

Static constructor has been executed at: 17:31:28
New instances: somethingA

New instances: somethingB

Instance "somethingA" has been created at: 17:31:28
Static constructor has been created at: 17:31:28

Instance "somethingB" has been created at: 17:31:30
Static constructor has been created at: 17:31:28
 */

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接