目标
我的目标是实现一个封闭的、公共的嵌套类,只能由其封闭类创建 - 而不使用反射。
这意味着嵌套类不能有任何公共或内部构造函数或任何公共或内部静态工厂方法。
先前的工作
几年前的这篇文章似乎是答案。(整个线程都有关于我要实现的内容的大量信息。)
它的工作原理非常简单:它利用了嵌套类可以访问其封闭类的静态字段以及嵌套类的静态构造函数。
封闭类声明了一个静态的 Func<NestedClassType, NestedClassCtorArgType>
委托,该委托返回嵌套类的实例,以便封闭类可以将该委托用作工厂方法。
嵌套类本身有一个静态构造函数,它将封闭类的静态工厂委托初始化为一个委托,该委托将创建嵌套类的实例。
问题
不幸的是,我无法按照那个答案中的方式使其工作。原因是嵌套类的静态构造函数在封闭类使用工厂方法之前没有被调用,因此会出现空引用异常。(如果您查看本问题末尾的示例程序,就会明白我的意思。)
我的解决方法
我已经通过以下方式解决了这个问题:
- 向嵌套类添加一个内部静态的
Initialise()
方法,它什么也不做。 - 向封闭类添加一个静态构造函数,该函数调用嵌套类的
Initialise()
方法。
这很好用,但它留下了一个像 internal static void Initialise()
方法的小问题。
我的问题
有没有避免这种做法的方法?我不能不想从我上面链接的原始帖子中漏掉什么。我是否误解了答案?
有没有聪明的方法强制运行嵌套类的静态构造函数在我调用试图创建嵌套类实例的代码之前?
还有其他问题吗?
(我知道我可以为嵌套类编写一个公共接口,并返回它。这个问题不是要解决这种方法!)
示例代码
这是我的示例代码。尝试运行它,它将打印“Test”。然后尝试注释掉标记为<--- If you comment this out, things won't work
的行并再次运行它。
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
Outer outer = new Outer();
Outer.Inner item = outer.Item("Test");
Console.WriteLine(item.Text);
}
}
public sealed class Outer
{
public Inner Item(string text)
{
return _nestedFactory(text);
}
// This static constructor calls the nested class's Initialise() method, which causes the
// nested class's static constructor to run, which then sets the enclosing class's
// _nestedFactory field appropriately.
static Outer()
{
Inner.Initialise(); // <--- If you comment this out, things won't work.
}
// This class has a private constructor.
// I only want class Outer to be able to create instances of it.
public sealed class Inner
{
private Inner(string value) // Secret private constructor!
{
text = value;
}
public string Text { get { return text; } }
static Inner()
{
_nestedFactory = text => new Inner(text);
}
internal static void Initialise(){}
readonly string text;
}
static Func<string, Inner> _nestedFactory;
}
}
internal Initialise()
方法,为什么不愿意使用一个internal
构造函数呢?这似乎是解决问题的更简单的方法... - Marc Gravellinternal
? - Marc Gravell