【问题标题】:Init static field befor calling any static method in C# [duplicate]在C#中调用任何静态方法之前初始化静态字段[重复]
【发布时间】:2018-05-02 03:00:29
【问题描述】:

在我的课堂上,有几种方法具有以下签名:

public static void SomeMethod()
{
 ...
}

这些方法中的大多数都依赖于私有静态字段的值。 在调用这些静态方法之前,调用者必须有任何方法可以为该字段赋值。

我想要一个 Random 对象供应用程序中的所有类使用。如何传递对该对象的引用以在另一个类的静态方法中使用它? 我在类中有一个带有静态方法和静态初始化程序的私有静态字段:

public static void Init(Random random)
{
  _random = random;
}

但是如何确保初始化器被调用呢?在每个方法中进行检查并抛出异常,在我看来是多余的。可能还有其他选择。

最后我找到了一个适合我的解决方案:

  1. 在包含应用程序入口点的类中定义公共静态属性:public static Random Rnd { get; } = new Random();

  2. 在其他类中定义private static Random _random

  3. 为包含此代码的其他类实现静态构造函数:

        Type type = Assembly.GetExecutingAssembly().EntryPoint.DeclaringType;
        var randomTypeProperties =
            type.GetProperties().Where(p => p.PropertyType == typeof(Random));
        foreach (var propertyInfo in randomTypeProperties)
        {
            _random = (Random)propertyInfo.GetValue(null);
        }
    

我可以将来自@Andy 的消息标记为答案,因为它毕竟是一个静态构造函数。

感谢所有参与讨论的人。


学习永远不会太晚。昨天,当我阅读设计模式时,我意识到 Singlton 正是我所需要的:

public sealed class RandomAsSingleton : Random
{
    private static volatile RandomAsSingleton _instance;
    private static readonly object _syncRoot = new object();

    private RandomAsSingleton() { }

    public static RandomAsSingleton Instance
    {
        get
        {
            lock (_syncRoot)
            {
                if (ReferenceEquals(_instance, null)) { _instance = new RandomAsSingleton(); }
                return _instance;
            }
        }
    }
}

我以前的解决方案现在在我看来有点难看。

【问题讨论】:

  • 我觉得我的问题有区别:静态构造函数没有参数。
  • 听起来你应该重新考虑设计。使它们成为 instance 方法,并且只公开一个接受字段初始值的构造函数。然后创建该对象的单个实例,并在任何需要它的地方使其可用(例如,使用 DI)。
  • 最后我找到了一个适合我的解决方案: 1. 在包含应用程序入口点的类中定义公共静态属性: public static Random Rnd { get; } = 新随机(); 2.在其他类中定义private static Random _random;
  • 我认为关键是你不能在静态构造函数中初始化静态变量?你正在有效地做到这一点,只是以一种迂回的方式。非常不清楚为什么你不能在这里只使用静态构造函数。 (您无法使用建议的方法指定自定义 Random。)
  • 3.为包含此代码的其他类实现静态构造函数:Type type = Assembly.GetExecutingAssembly ().EntryPoint.DeclaringType; var randomTypeProperties = type.GetProperties().Where(p => p.PropertyType == typeof(Random)); foreach (var propertyInfo in randomTypeProperties) { _random = (Random)propertyInfo.GetValue(null); }

标签: c# static-methods


【解决方案1】:

您可能想要使用静态构造函数

// Static constructor is called at most one time, before any
// instance constructor is invoked or member is accessed.
static SimpleClass()
{
    // set your private static field
}

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors

【讨论】:

  • 我知道静态构造函数。但就我而言,静态字段的值取决于外部代码。
  • 那不是静态的,给我们看例子。你的问题太广泛了,所以它是重复的。如果您认为您的问题不同,请详细说明以显示差异。更加详细一些。 @retrograde.su
  • 更详细地说,我希望有一个 Random 对象供应用程序中的所有类使用。如何传递对该对象的引用以在另一个类的静态方法中使用它?
  • 我在类中有一个带有静态方法和静态初始化器的私有静态字段: public static void Init(Random random) { _random = random; }。但是如何确保调用了初始化程序?在每个方法中进行检查并抛出异常,在我看来是多余的。可能还有其他选择。
猜你喜欢
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多