Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C在受保护函数中返回一个私有类型,其中所有子类都可以访问私有类型_C# - Fatal编程技术网

C# C在受保护函数中返回一个私有类型,其中所有子类都可以访问私有类型

C# C在受保护函数中返回一个私有类型,其中所有子类都可以访问私有类型,c#,C#,我有两个类,BaseO和PrivateO,在另一个类Overflow中定义。BaseO是公共类,PrivateO是私有类。我还有一个到BaseO的child类,叫做ChildO,也是公共的 现在,在BaseO中,我想定义一个受保护的函数protectedprivate0 getPrivate;,哪个孩子可以访问。但这是不允许的,因为getPrivate的可访问性与PrivateO不同 我理解为什么这是一个问题,如果有人要从外部继承BaseO,他们需要访问PrivateO,而他们没有 现在我已经通

我有两个类,BaseO和PrivateO,在另一个类Overflow中定义。BaseO是公共类,PrivateO是私有类。我还有一个到BaseO的child类,叫做ChildO,也是公共的

现在,在BaseO中,我想定义一个受保护的函数protectedprivate0 getPrivate;,哪个孩子可以访问。但这是不允许的,因为getPrivate的可访问性与PrivateO不同

我理解为什么这是一个问题,如果有人要从外部继承BaseO,他们需要访问PrivateO,而他们没有

现在我已经通过使用对象和类型转换解决了这个问题,但是我想做得更正确一些。是否有一种方法可以指定BaseO不打算从溢出外部继承

内部是一个想法,但我希望即使代码不在不同的程序集中也能这样做

我可以访问.NET4.5和C5,但是任何更新的版本都会很有趣

示例代码:

public static class Overflow
{
    private class PrivateO
    {
        public int foo;
    }

    public class BaseO
    {
        protected PrivateO GetPrivate() // inconsistent accessibility
        {
            return new PrivateO();
        }
    }

    public class ChildO : BaseO
    {
        private int foo;
        public ChildO()
        {
            this.foo = GetPrivate().foo; // <- desired behavior
        }
    }
}
编辑:注意示例代码只是一个示例。真正的PrivateO类要复杂得多,因此它不仅仅是检索int的问题。它还返回私有构建器类和其他非平凡的数据结构


编辑2:将溢出更改为静态类,以强调在这种情况下,它更多地用作名称空间而不是实例类。

您可以使该类受到保护并将其嵌入BaseO:

class Overflow
{


    public class BaseO
    {
        protected class PrivateO
        {
            public int foo;
        }

        protected PrivateO GetPrivate() 
        {
            return new PrivateO();
        }
    }

    public class ChildO : BaseO
    {
        private int foo;
        public ChildO()
        {
            this.foo = GetPrivate().foo; // <- desired behavior
        }
    }
}

您可以使该类受到保护并将其嵌入BaseO中:

class Overflow
{


    public class BaseO
    {
        protected class PrivateO
        {
            public int foo;
        }

        protected PrivateO GetPrivate() 
        {
            return new PrivateO();
        }
    }

    public class ChildO : BaseO
    {
        private int foo;
        public ChildO()
        {
            this.foo = GetPrivate().foo; // <- desired behavior
        }
    }
}

为私有/受保护的属性提供访问器属性:

class Overflow
{
    private class PrivateO
    {
        public int foo;
    }

    public class BaseO
    {       
        PrivateO privateO = new PrivateO();
        public int PrivateFoo => privateO.foo;
    }

    public class ChildO : BaseO
    {
        private int foo;
        public ChildO()
        {
            this.foo = PrivateFoo;
        }
    }

}为私有/受保护的属性提供访问器属性:

class Overflow
{
    private class PrivateO
    {
        public int foo;
    }

    public class BaseO
    {       
        PrivateO privateO = new PrivateO();
        public int PrivateFoo => privateO.foo;
    }

    public class ChildO : BaseO
    {
        private int foo;
        public ChildO()
        {
            this.foo = PrivateFoo;
        }
    }
}

有没有一种方法可以指定BaseO不打算被继承 从外部溢出

我想这就是为什么

当应用于一个类时,sealed修饰符会阻止其他类 从中继承

有没有一种方法可以指定BaseO不打算被继承 从外部溢出

我想这就是为什么

当应用于一个类时,sealed修饰符会阻止其他类 从中继承

如果Base0永远不需要从外部实例化,并且所有运行时类型都将是像Child0这样的运行时类型,则可以将继承限制为嵌套类型:

public class BaseO
{   
    //private ctor avoids anyone extending this class
    //outside Base0 
    private Base0 { }   
    PrivateO privateO = new PrivateO();
    public int PrivateFoo => privateO.foo;

    public class ChildO : BaseO
    {
        private int foo;
        public ChildO()
        {
            this.foo = PrivateFoo;
        }
    }
}
现在您可以:

var child0 = new Overflow.Base0.Child0();
但您不能执行以下两项操作:

如果您确实需要允许var base0=new Overflow.base0;如果你运气不好,你不能两全其美;如果有人可以重新创建一个Base0并且它没有被密封,那么他将能够从中继承

在这种情况下,您的最佳选择是:

仅允许在同一程序集内部构造函数中继承 不要在溢出外部公开Base0和Child0,公开接口IBase0 执行运行时检查并从程序集外部清除任何调用Base0的类。讨厌!我不知道我为什么要这么说。 如果Base0永远不需要从外部实例化,并且所有运行时类型都将是像Child0这样的运行时类型,则可以将继承限制为嵌套类型:

public class BaseO
{   
    //private ctor avoids anyone extending this class
    //outside Base0 
    private Base0 { }   
    PrivateO privateO = new PrivateO();
    public int PrivateFoo => privateO.foo;

    public class ChildO : BaseO
    {
        private int foo;
        public ChildO()
        {
            this.foo = PrivateFoo;
        }
    }
}
现在您可以:

var child0 = new Overflow.Base0.Child0();
但您不能执行以下两项操作:

如果您确实需要允许var base0=new Overflow.base0;如果你运气不好,你不能两全其美;如果有人可以重新创建一个Base0并且它没有被密封,那么他将能够从中继承

在这种情况下,您的最佳选择是:

仅允许在同一程序集内部构造函数中继承 不要在溢出外部公开Base0和Child0,公开接口IBase0 执行运行时检查并从程序集外部清除任何调用Base0的类。讨厌!我不知道我为什么要这么说。
不幸的是,PrivateO在许多其他上下文中使用,并且需要存在于Overflow类中。如果它仅在一个程序集中使用,则必须将其设置为内部类,或者将其公开。如果一个类在多个上下文中使用,将其私有化是没有意义的。它在溢出类内的多个上下文中使用,而不是在溢出类外。基本上,我只是在寻找一种方法,通过将PrivateO相关的代码放在基中,来避免为所有BaseO的子类反复重写相同的代码。我认为,由于BaseO不是从“溢出”继承的,所以至少必须将其设为内部代码。如果BaseO不是从“溢出”继承的,那又有什么关系呢?即使它这样做了,也会有同样的可访问性问题。不幸的是,PrivateO在许多其他上下文中使用,并且需要存在于Overflow类中。如果它仅在一个程序集中使用,则必须将其设置为内部类,或者将其公开。如果一个类在多个上下文中使用,那么将其私有化是没有意义的
在溢出类中,而不是在它之外。基本上,我只是在寻找一种方法,通过将PrivateO相关的代码放在基中,来避免为所有BaseO的子类反复重写相同的代码。我认为,由于BaseO不是从“溢出”继承的,所以至少必须将其设为内部代码。如果BaseO不是从“溢出”继承的,那又有什么关系呢?即使它这样做了,它仍然会有相同的可访问性问题。sealed阻止任何类型的继承,除非我误解了它?是的,它还会阻止您在项目中从它继承。假设您需要这样做,那么返回一个从BaseO继承的新密封类如何?密封不是访问修饰符,它与askedsealed阻止任何类型的继承无关,除非我误解了它?是的,它还会阻止您在项目内部从它继承。假设您需要这样做,那么返回一个从BaseO继承的新的密封类如何?密封不是访问修饰符,它与询问的问题无关。这要求我在BaseO中包装所有希望从PrivateO使用的功能,对吗?是的。把接口想象成一个dto。这是个好主意,但不幸的是,真正的PrivateO类相当复杂,还返回更多的私有类。示例代码是一种简化。这要求我在BaseO中包装所有希望从PrivateO使用的功能,对吗?是的。把接口想象成一个dto。这是个好主意,但不幸的是,真正的PrivateO类相当复杂,还返回更多的私有类。示例代码是一种简化。Base0实例是否在溢出之外使用过,还是始终是Child0运行时对象?Base0实例是否在溢出之外使用过,还是始终是Child0运行时对象?