[英]C# Inheritance to hide inherited Members
我看了其他线程像这样 ,但他们并没有为我工作。
我有两节课:
public class ClassA
{
public string _shouldBeInteger;
public string _shouldBeBool;
public string _shouldBeDateTime;
}
public class ClassB : ClassA
{
public int? shouldBeInteger
{
get { return (_shouldBeInteger != null) ? Convert.ToInt32(Convert.ToDouble(_shouldBeInteger)) : new int?(); }
set { _shouldBeInteger = Convert.ToString(value); }
}
//... same thing with datetime etc.
}
如果我现在创建一个ClassB的新对象,我得到
_shouldBeInteger, _shouldBeBool, _shouldBeDateTime;
shouldBeInteger,shouldBeBool,shouldBeDateTime
但我想隐藏_variables给用户。 在ClassB中将它们设置为私有将覆盖它们,但我需要访问它们才能解析字符串值。
更新
有一个ClassC填充ClassAs的值,这主要是它们必须可写的原因。 我没有办法改变它的工作方式,但我完全控制了ClassA和ClassB
ClassC //not changeAble for me
{
//infomagic filling values of ClassA
}
将ClassA变量设置为private将不起作用,因为ClassA的程序员以一种奇怪的方式生成它。
解
因为ClassA需要是可写的,但是对于继承的其他类不可读,我终于得到了这个:
ClassA
{
public string _shouldBeInteger { protected get; set; }
//and so on
}
这会导致ClassB与theese属性一起使用,而不会将它们放在外面。 Intellisense仍会显示它们,但您可以考虑使用:
[EditorBrowsable(EditorBrowsableState.Never)]
解决这个问题。
谢谢大家。
我认为您可以使用以下方法解决问题:
public class ClassA
{
protected string _shouldBeInteger;
protected string _shouldBeBool;
protected string _shouldBeDateTime;
}
所以这些变量可以被派生类访问,但不能访问用户。
用户更新后编辑:
我不知道这对你来说是否是一个vali解决方案,但请尝试:
public class ClassB : ClassA
{
public new int? _shouldBeInteger
{
get { return (base._shouldBeInteger != null) ?
Convert.ToInt32(Convert.ToDouble(base._shouldBeInteger)) :
new int?(); }
set { base._shouldBeInteger = Convert.ToString(value); }
}
}
继承不能像你想象的那样隐藏成员。 new
修饰符用于“隐藏”基础成员,但在与基本类型交谈时不会很好。
http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
您可以更改字段的访问级别(首选方式),也可以包装类而不是继承它,并提供简单的传递方法来委托包装类。 这称为适配器模式 :
public class ClassB
{
private ClassA _wrappedClass;
}
另外,您的公共字段遵循通常用于私有字段的命名约定。
派生类所需的访问级别protected
。 如果成员是公开使用但在同一个程序集中,则可以使用protected internal
。 如果成员被其他程序集公开使用......我建议重构。
问题是您在基类中声明了字段public。 为了不违反继承的多态性,基类中的任何公共事物也必须在所有派生类中都是公共的。 如果你可以改变它,你永远不能确定ClassB可以传递给期望ClassA的东西。
因此,正如其他人所建议的那样,您可能希望将基类字段声明为protected,这类似于private,但派生类可以看到它们。
但是,如果您确实需要通过ClassA的实际实例访问它们,则可以将它们声明为private,并为它们提供虚拟公共属性,然后派生类可以覆盖它们。 这至少允许派生类改变它们的行为,但它实际上仍然无法隐藏它们。
如果这也不适合,那么可能值得考虑使用组合而不是继承,因为替换原则实际上妨碍了你的方式,这是继承的基础。
如果您无法控制ClassA,则需要创建一个包装器/适配器类,如下所示:
public class ClassB
{
private readonly _classA = new ClassA();
public int? shouldBeInteger
{
get
{
return (this._classA._shouldBeInteger != null)
? Convert.ToInt32(Convert.ToDouble(this._classA._shouldBeInteger))
: new int?();
}
set
{
this._classA._shouldBeInteger = Convert.ToString(value);
}
}
}
public class ClassB
{
private int shouldBeInteger;
public int ShouldBeInteger
{
get { return shouldBeInteger; }
set { shouldBeInteger = value; }
}
}
要么
public class ClassB
{
public int ShouldBeInteger{ get; set; }
}
在这两种情况下,ShouldBeInteger都可以在课外访问。
在第一种情况下,有一个私人领域,在课外无法访问,
私人领域的价值可以通过公共领域设定。
在第二种情况下,编译器会自动创建一个私有支持字段并执行相同操作
过程如上。 这是自动实现的属性。
希望这可以帮到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.