【问题标题】:Is there an api to bypass the static constructor of a class有没有绕过类的静态构造函数的api
【发布时间】:2019-01-29 05:54:57
【问题描述】:

有没有一种方法可以在不执行静态构造函数的情况下初始化包含静态构造函数(引发异常)的类?

到目前为止我已经尝试过这些:

Activator.CreateInstance(typeof(Foo));

FormatterServices.GetUninitializedObject(typeof(Foo));

var s = new XmlSerializer(typeof(Foo));
Foo f = (Foo)s.Deserialize(new StringReader("<Foo></Foo>"));

除了使用带有 MS Fakes 或 TypeMock 之类的 CRL Profiler api 之外,这可以使用基类库中的任何 API 来完成,或者可能是非托管的。

我想使用的示例类。

public class Foo
{
    static Foo()
    {
        throw new Exception("Populate Bar from the database, which isn't available.");
    }

    public int Bar { get; set; }
}

【问题讨论】:

  • 没有。来自Static Constructors:“静态构造函数......在创建第一个实例或引用任何静态成员之前自动调用。”
  • 获得参考后您会如何处理? default(Foo) 够吗?
  • 为什么你的类有一个抛出异常的静态构造函数?也许你的努力可以用来纠正这个问题。
  • 我的精神力量告诉我这是一个 XY 问题。
  • 尝试编写一个对其正在测试的代码做疯狂事情的​​自动化测试几乎没有什么价值,比如通过阻止其静态构造函数运行来违反它的合同。到那时,您的测试不再有价值,错误很可能是您使用不当造成的,而不是设计使用中的错误,并且您将无法确信您的测试正在捕捉问题,因为您'正在阻止部分代码运行。要么构建测试以正确使用代码,要么不要浪费时间进行没有告诉你任何事情的测试。

标签: c#


【解决方案1】:

不,我不知道,至少直接知道。

静态构造函数会在anything发生在类中的任何静态事件(方法、属性……)上,或者当您创建该类的第一个实例时自动调用(如果可能的话)。

这意味着,基本上,不管你喜欢/不想要,它们总是被调用。它总是自动的,而且总是会发生。

但是,一种选择是使用一些讨厌的反射来提取工作代码,替换(或完全删除)静态构造函数并从头开始重建类。 This 可能对此有所帮助。

问题是出现了另一个大问题:如何在使用期间替换该类型。如果它来自接口,可能会更容易,但如果它是直接调用的具体类型,那么您将面临很大的挑战。

现在,如果您将其提升到更高的抽象级别,则可以使用其他方法解决此问题,例如将该请求代理到其他数据库,甚至将其翻译成另一种语言。

【讨论】:

  • 感谢您的意见。我还没有找到没有 MS Fakes 或 Typemock 的方法。我可以访问源代码,并且不需要使用反射。我不能代替班级。我也无法替代它的用法。这两部分都是我无权更改的代码。
  • 如果你没有权限替换类,你很可能没有权限绕过构造函数,这是有一个非常具体的原因。即使绕过这是可能的......
猜你喜欢
  • 2012-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-03
  • 2012-07-15
  • 1970-01-01
  • 2017-11-23
  • 1970-01-01
相关资源
最近更新 更多