加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 01:54:44 所属栏目:百科 来源:网络整理
导读:目标 我的目标是实现一个密封的公共嵌套类,它只能由其封闭的类创建 – 不使用反射. 这意味着嵌套类不能具有任何公共或内部构造函数或任何公共或内部静态工厂方法. 之前的工作 This post from a couple of years ago seems to be the answer.(整个帖子都有很
目标

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

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

之前的工作

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读