在不调用构造函数的情况下调用实例方法

时间:2009-11-18 15:40:24

标签: c# constructor methods instance

假设我有以下课程,我不允许改变:

public class C
{
    public C() { CreateSideEffects(); }
    public void M() { DoSomethingUseful(); }
}

我必须在不调用构造函数的情况下调用M.有可能吗?

5 个答案:

答案 0 :(得分:8)

即使它是不是一个好的想法,是的,我们可以;) 与FormatterServices.GetUninitializedObject

C uninitializedC = (C)FormatterServices.GetUninitializedObject(typeof(C));
uninitializedC.M();

答案 1 :(得分:7)

没有。因为C.M()是一个实例方法,所以需要创建一个实例,这意味着调用构造函数。

C是您的团队拥有的课程吗?如果确实如此,但你有责任不管它,那么你最好还是游说:

  1. 要重构和删除的副作用
  2. C.M()方法功能移出到另一个类或静态。
  3. 如果C来自第三方,您将遇到麻烦,可能需要在执行拥有的方法中复制C.M()的功能

答案 2 :(得分:4)

是的,你可以!

毋庸置疑,这是一个糟糕的设计,但你已经知道并且无法改变它。如果必须,你可以尝试局部嘲笑这个班级。

编辑:刚才意识到我的例子使用Java而不是C#。但是,@ Guillaume提供了C#的代码示例。显然,它甚至内置于运行时API中!

在Java中,使用Mockito,这确实有效:

C c = Mockito.mock(C);
Mockito.doCallRealMethod().when(c).M();
// If M() isn't a void method
// when(c.M()).thenCallRealMethod();
c.M();

但是,在这种情况下,M()不能依赖于构造函数中设置的任何状态。

有关部分模拟的详细信息,请查看此FAQ Question。但是,模拟主要用于测试。

答案 3 :(得分:1)

为了调用实例方法,您需要一个实例!并且 - 有充分的理由 - 获得一个的唯一方法是通过构造函数。否则整个对象可能处于不确定或无用状态,因为尚未进行初始化。所以,即使有某种黑客攻击,也不是一个好的选择!

没有实例可以调用的唯一类成员是静态方法。

答案 4 :(得分:1)

我不会告诉你这是一个坏主意,因为听起来你已被告知足够了。哦,对不起我想我刚刚做了......无论如何这里是怎么做的:

using System.Runtime.Serialization;

    C myInstance = FormatterServices.GetUninitializedObject(typeof(C));
    myInstance.M();

上面的'GetUninitializedObject'方法返回一个对象的实例而不调用任何实例ctor(显然任何静态类型的ctor仍然会运行)。然后,您可以根据需要戳实例字段,或者只是调用方法。

再次,整体上是一个坏主意;)