C# C在受保护函数中返回一个私有类型,其中所有子类都可以访问私有类型
我有两个类,BaseO和PrivateO,在另一个类Overflow中定义。BaseO是公共类,PrivateO是私有类。我还有一个到BaseO的child类,叫做ChildO,也是公共的 现在,在BaseO中,我想定义一个受保护的函数protectedprivate0 getPrivate;,哪个孩子可以访问。但这是不允许的,因为getPrivate的可访问性与PrivateO不同 我理解为什么这是一个问题,如果有人要从外部继承BaseO,他们需要访问PrivateO,而他们没有 现在我已经通过使用对象和类型转换解决了这个问题,但是我想做得更正确一些。是否有一种方法可以指定BaseO不打算从溢出外部继承 内部是一个想法,但我希望即使代码不在不同的程序集中也能这样做 我可以访问.NET4.5和C5,但是任何更新的版本都会很有趣 示例代码:C# C在受保护函数中返回一个私有类型,其中所有子类都可以访问私有类型,c#,C#,我有两个类,BaseO和PrivateO,在另一个类Overflow中定义。BaseO是公共类,PrivateO是私有类。我还有一个到BaseO的child类,叫做ChildO,也是公共的 现在,在BaseO中,我想定义一个受保护的函数protectedprivate0 getPrivate;,哪个孩子可以访问。但这是不允许的,因为getPrivate的可访问性与PrivateO不同 我理解为什么这是一个问题,如果有人要从外部继承BaseO,他们需要访问PrivateO,而他们没有 现在我已经通
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运行时对象?