微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 如何实现一个只能由其封闭类创建的密封的公共嵌套类?

目标

我的目标是实现一个密封的公共嵌套类,它只能由其封闭的类创建 – 不使用反射.

这意味着嵌套类不能具有任何公共或内部构造函数或任何公共或内部静态工厂方法.

之前的工作

This post from a couple of years ago seems to be the answer.(整个帖子都有很多关于我想要实现的信息.)

它的工作原理非常简单:它利用了嵌套类可以访问其封闭类的静态字段以及嵌套类的静态构造函数这一事实.

封闭类声明静态Func< nestedClasstype,nestedClassCtorArgType> delegate返回嵌套类的实例,以便封闭类可以将该委托用作工厂方法.

嵌套类本身有一个静态构造函数,它将封闭类的静态工厂委托初始化为一个委托,该委托将创建嵌套类的实例.

问题

不幸的是,我无法让它工作,因为它是在答案中写的.原因是在封闭类使用工厂方法之前不会调用嵌套类的静态构造函数,因此存在空引用异常. (如果你看看这个问题末尾的示例程序,你会看到我的意思.)

我的解决方法

解决了这个问题如下:

>向嵌套类添加一个不执行任何操作的内部静态Initialise()方法.
>向封闭类添加一个静态构造函数,该构造函数调用嵌套类的Initialise()方法.

这样可以正常工作,但它会在内部静态void Initialise()方法的形状中留下一些痈.

我的问题

有没有办法避免这种做法?我不禁想到我错过了上面链接的原帖.我误解了答案吗?

调用尝试创建嵌套类实例代码之前,是否有一种聪明的方法可以强制嵌套类的静态构造函数运行?

这种方法还有其他问题吗?

(我知道我可以为嵌套类编写一个公共接口,然后返回它.这个问题不是那样解决它!)

示例代码

这是我的示例代码.尝试运行它,它将打印“测试”.然后尝试注释掉标记为< ---的行.如果您对此进行注释,则事情将无效并再次运行.

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;
    }
}

解决方法

如果需要强制运行类构造函数而不引用类型,则可以使用此代码

static Outer()
{
    System.Runtime.CompilerServices.RuntimeHelpers.runclassConstructor(typeof (Inner).TypeHandle);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐