类型初始化程序在访问静态属性时引发异常

时间:2011-11-16 04:51:11

标签: c# exception static

我定义了以下静态属性:

namespace Foo
{
    public class Bar
    {
        private static byte[] aes256Key = null;
        internal static byte[] Aes256Key
        {
            get
            {
                if (aes256Key != null)
                {
                    return aes256Key;
                }

                aes256Key = new byte[32];

                // Fill in key...

                return aes256Key;
            }
        }
    }
}

在内部命名空间中的另一个类中,我正在访问此属性:

namespace Foo.Cryptography
{
    public class SymmetricCryptography
    {
        internal static void EncryptFile(
            string sourceFile,
            string destinationFile)
        {
            // <snip>
            AesManaged aes = new AesManaged();
            aes.BlockSize = 128;
            aes.KeySize = 256;
            aes.Key = Bar.Aes256Key; // Accessing the key here
            // <snip>
        }
    }
}

Foo.Cryptography由可执行控制台应用程序使用。当我从构建环境手动运行此控制台应用程序时,我没有看到任何问题。但是,当可执行文件在构建过程的上下文中运行时(在具有可能不同环境的服务器上),我看到以下运行时异常:

The type initializer for 'Foo.Bar' threw an exception.

VS2008中的可执行项目引用了Foo项目,该项目定义了Foo命名空间。

我在这里做了什么根本错误的事吗?可能导致这种情况的原因是什么?

3 个答案:

答案 0 :(得分:1)

在没有看到完整代码的情况下,很难在'静态世界'上工作。尽管如此,为了找到原因,以下是您可以(个人)工作的几个方面。

aes256Key = new byte[32];
// Fill in key...
return aes256Key;
  1. 检查“填写密钥”逻辑中的可能异常是合理的

  2. 为此Bar定义静态构造函数并初始化所有静态字段。

  3. 确保您致电RuntimeHelpers.RunClassConstructor(typeof(Bar).TypeHandle)                  甚至在访问任何static/instance field/member/method之前。

    static void Main(string[] args)

    {

    RuntimeHelpers.RunClassConstructor(typeof(Bar).TypeHandle);
    byte[] bt = Bar.Aes256Key;
    

    }

  4. RuntimeHelpers.RunClassConstructor确实要求运行时调用静态构造函数,而不管CLI中指定的原因如何。这确保了确定性单元初始化顺序。这是必要的,因为类型初始化器相信Lazy初始化。

答案 1 :(得分:0)

Foo.Aes256Key甚至不会编译,因为Foo是您的命名空间......

答案 2 :(得分:0)

Foo.Cryptography和Foo.Bar是否在同一个dll中?听起来像依赖性问题,就像它在包含Foo.Bar的硬盘驱动器上找不到dll。

编辑:好的,上面显然不是问题...

你在初始化程序中使用的类可能需要一个不在生产机器上的依赖...我没有在你的代码中看到任何内容,但可能是你遗漏的部分。我假设你在生产机器上加载了完整的.net框架。您是否正在使用您遗漏的代码中的任何对象,这些对象将直接或间接地从内部或第三方dll中的任何其他代码调用代码?

另一个编辑:实际上我认为您遗漏的部分中的代码不会导致此错误,因为它不应该在类初始化时自动运行。你确定你没有遗漏任何其他代码吗?我在这里看不到任何看起来会导致这种异常的事情。

看起来像“private static byte [] aes256Key = null;”是唯一能够导致此异常的行,但我认为很明显这条线不会这样做。