请向我解释一下静态构造函数的用法.我们为什么以及何时创建静态构造函数,是否可以重载一个?
我想要一个具有私有静态数据成员的类(包含所有字符az的向量).在java或C#中,我可以创建一个"静态构造函数",它将在我创建类的任何实例之前运行,并设置类的静态数据成员.它只运行一次(因为变量是只读的,只需要设置一次),因为它是类的一个函数,它可以访问它的私有成员.我可以在构造函数中添加代码来检查向量是否已初始化,如果不是,则初始化它,但是这会引入许多必要的检查,并且似乎不是问题的最佳解决方案.
我想到,因为变量只是只读的,所以它们只能是公共的静态const,所以我可以在类外面设置它们,但是再一次,它看起来有点像丑陋的黑客.
如果我不想在实例构造函数中初始化它们,是否可以在类中拥有私有静态数据成员?
namespace MyNameSpace
{
static class MyClass
{
static MyClass()
{
//Authentication process.. User needs to enter password
}
public static void MyMethod()
{
//Depends on successful completion of constructor
}
}
class Program
{
static void Main(string[] args)
{
MyClass.MyMethod();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我假设的顺序
现在在任何情况下,如果4将在2之前开始,我被搞砸了.可能吗?
我想在不创建实例的情况下执行类的静态构造函数(即我想"加载"类).我怎么做?
加分问题:.NET 4和旧版本之间有什么区别吗?
编辑:
private static readonly字段因此不能在方法中运行.以下是初始化静态只读字段的两种不同方法.两种方法之间有区别吗?如果是的话,什么时候应该优先于另一个呢?
class A
{
private static readonly string connectionString =
WebConfigurationManager.ConnectionStrings["SomeConnection"].ConnectionString;
}
class B
{
private static readonly string connectionString;
static B()
{
connectionString =
WebConfigurationManager.ConnectionStrings["SomeConnection"].ConnectionString;
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个关于Value类型中的类型构造函数的问题.这个问题的灵感来自Jeffrey Richter在CLR中通过C#3rd ed编写的内容,他说(在第195页 - 第8章)你不应该在值类型中实际定义类型构造函数,因为有时候CLR不会调用它.
所以,例如(好吧......实际上是Jeffrey Richters的例子),即使通过查看IL,我也无法解决为什么在以下代码中没有调用类型构造函数:
internal struct SomeValType
{
static SomeValType()
{
Console.WriteLine("This never gets displayed");
}
public Int32 _x;
}
public sealed class Program
{
static void Main(string[] args)
{
SomeValType[] a = new SomeValType[10];
a[0]._x = 123;
Console.WriteLine(a[0]._x); //Displays 123
}
}
Run Code Online (Sandbox Code Playgroud)
因此,对类型构造函数应用以下规则,我只是看不出为什么根本没有调用上面的值类型构造函数.
所以......我无法理解为什么我看不到这个类型的数组正在被构造.
我最好的猜测是它可能是:
最佳实践等帮助,我只是对它非常感兴趣,因为我希望能够亲眼看到它为什么不被调用.
编辑:我在下面添加了我自己的问题的答案,只是引用杰弗里里希特所说的.
如果有人有任何想法,那将是辉煌的.非常感谢,詹姆斯
静态构造函数用于初始化任何静态数据,或执行仅需执行一次的特定操作.在创建第一个实例或引用任何静态成员之前自动调用它.
最后一部分(关于何时被自动调用)让我陷入了一个循环; 直到阅读那部分我认为通过简单地以任何方式访问一个类,我可以确定它已经调用了它的基类的静态构造函数.测试和检查文档表明情况并非如此; 看起来基本类的静态构造函数不能保证在访问该基类的成员之前运行.
现在,我想在大多数情况下,当您处理派生类时,您将构造一个实例,这将构成正在创建的基类的实例,因此将调用静态构造函数.但是,如果我只处理派生类的静态成员,那么呢?
为了使这更具体一点,我认为下面的代码可以工作:
abstract class TypeBase
{
static TypeBase()
{
Type<int>.Name = "int";
Type<long>.Name = "long";
Type<double>.Name = "double";
}
}
class Type<T> : TypeBase
{
public static string Name { get; internal set; }
}
class Program
{
Console.WriteLine(Type<int>.Name);
}
Run Code Online (Sandbox Code Playgroud)
我假设访问Type<T>该类会自动调用静态构造函数TypeBase; 但事实并非如此.Type<int>.Name是null,并且上面的代码输出空字符串.
除了创建一些虚拟成员(就像Initialize()什么都不做的静态方法)之外,还有更好的方法来确保在使用任何派生类型之前调用基类型的静态构造函数吗?
如果没有,那么......虚拟成员就是!
我想为下面的课程编写单元测试.
如果名称不是"MyEntity",则mgr应为空白.
负单元测试
使用Manager私有访问器我想将名称更改为"Test",以便mgr应为null.然后将验证mgr值.为了实现这一点,我想显式调用静态构造函数,但是当我使用静态构造函数调用时
Manager_Accessor.name = "Test"
typeof(Manager).TypeInitializer.Invoke(null, null);
Run Code Online (Sandbox Code Playgroud)
name始终设置为"MyEntity"如何将名称设置为"Test"并调用静态构造函数.
public class Manager
{
private static string name= "MyEntity";
private static object mgr;
static Manager()
{
try
{
mgr = CreateMgr(name);
}
catch (Exception ex)
{
mgr=null;
}
}
}
Run Code Online (Sandbox Code Playgroud) 在C++中没有静态构造函数的基本原理是什么?
如果允许,我们将以非常有组织的方式在一个地方初始化其中的所有静态成员,如下所示:
//illegal C++
class sample
{
public:
static int some_integer;
static std::vector<std::string> strings;
//illegal constructor!
static sample()
{
some_integer = 100;
strings.push_back("stack");
strings.push_back("overflow");
}
};
Run Code Online (Sandbox Code Playgroud)
在静态构造函数的缺失中,很难有静态向量,并用值填充它,如上所示.静态构造函数优雅地解决了这个问题.我们可以以非常有组织的方式初始化静态成员.
那么为什么'C++没有静态构造函数?毕竟,其他语言(例如,C#)具有静态构造函数!
c++ language-features constructor language-design static-constructor
我有一个带有静态构造函数的静态类.我需要以某种方式将参数传递给这个静态类,但我不确定最好的方法是什么.你会推荐什么?
public static class MyClass {
static MyClass() {
DoStuff("HardCodedParameter")
}
}
Run Code Online (Sandbox Code Playgroud) c# ×8
.net ×2
c++ ×2
constructor ×2
initializer ×2
static ×2
c#-2.0 ×1
c#-3.0 ×1
c#-4.0 ×1
class ×1
clr ×1
inheritance ×1
mstest ×1
private ×1
struct ×1