做一个只读属性写在派生类中 [英] Make a read only property writable in the derived class
问题描述
我想实现的是以下内容:
我都在BaseClass的声明的属性。如果此属性是通过基类的指针访问,只有吸气应该可用,但如果使用派生类指针我希望能够获取和设置该属性。因此,智能感知不应该甚至显示为基本指针的制定者。
What I want to achieve is the following : I have a property declared in the BaseClass. If this property is accessed via the base class' pointer, only the getter should be available but if the derived class pointer is used I want to be able to get and set the property. So the intellisense should not even show a setter for the base pointer.
public class BaseClass
{
public virtual int MyProperty
{
get { return 1; }
set {;}//This would show the setter in Intellisense
}
}
public class DerivedClass : BaseClass
{
int intValue;
public override int MyProperty
{
set { intValue = value;}
}
}
一个现实的例子:结果
考虑,你必须从人得到的亲子班的情况类。想象一个属性-RestrictionLevel,其中两者都可以读,但只有父可以设置的值。有没有更好的方法来设计这种情况?
A realistic example:
Consider a situation where you have a Parent and Child class derived from the Person class. Imagine a property -RestrictionLevel, where both can read it but only the parent can set the value. Is there a better way to design this situation?
推荐答案
我能想到的唯一的办法就是用新影着财产之一:
The only way I could think of is to shadow the property with a new one:
public class DerivedClass : BaseClass
{
int intValue;
public new int MyProperty
{
get { return intValue; }
set { intValue = value; }
}
}
注意属性是如何声明新
而不是倍率
。这意味着,当然,那 myProperty的
类型 DerivedClass
有无关 myProperty的
类型的BaseClass
的,那就是正好有相同的名称(从而隐藏从基类的)一个全新的属性。
Notice how the property is declared new
instead of override
. This means, of course, that MyProperty
of the type DerivedClass
has nothing to do with MyProperty
of the type BaseClass
, it's a brand new property that just happens to have the same name (thus hiding the one from the base class).
结果是这样的:
DerivedClass d = new DerivedClass();
d.MyProperty = 42;
BaseClass b = new DerivedClass();
b.MyProperty = 42; /* compilation error: Property or indexer
'TheNamespace.BaseClass.MyProperty'
cannot be assigned to -- it is
read only */
此外,如在注释@silky状态:
Also, as @silky states in the comment:
(虽然我建议你把它和
父,指同一变量
避免一个非常混乱的局面),但
我真的不认为这会永远
是合适的。
(though I suggest you make it, and the parent, refer to the same variable to avoid a very confusing situation) but I really don't think this would ever be appropriate.
...你可能需要有新的属性访问从基类(一个通过 base.MyProperty
,与受保护的setter完成)。例如考虑以下内容:
...you may want to have the new property access the one from the base class (through base.MyProperty
, completed with a protected setter). Consider the following for instance:
DerivedClass d = new DerivedClass();
d.MyProperty = 42;
BaseClass b = d;
Console.WriteLine(b.MyProperty); // prints 1
这表示使用时,我总觉得有点脏新
(其中,当我想想,我不知道,我在生产代码究竟做了)。
That said, I always feel a little dirty when using new
(which, when I think about it, I am not sure that I have actually done in production code).
更新结果
既然你给(我在某种程度上理解,一个父
是能够将<$示例场景C $ C> RestrictionLevel 儿童),它可以解决这样的>:
Update
Given the example scenario that you give (that I interpret in a way that a Parent
is to be able to set the RestrictionLevel
of a Child
), it could be solved like this:
public enum RestrictionLevel
{
Low,
Medium,
Grounded
}
public class Person
{
public RestrictionLevel RestrictionLevel { get; private set; }
protected static void SetRestrictionLevelInternal(Person person, RestrictionLevel restrictionLevel)
{
person.RestrictionLevel = restrictionLevel;
}
}
public class Child : Person { }
public class Parent : Person
{
public void SetRestrictionLevel(Child child, RestrictionLevel restrictionLevel)
{
SetRestrictionLevelInternal(child, restrictionLevel);
}
}
这意味着下面的代码是有效的:
This means that the following code is valid:
Child c = new Child();
Parent p = new Parent();
p.SetRestrictionLevel(c, RestrictionLevel.Grounded);
...但是这个人是不是:
...but this one is not:
Child c = new Child();
c.SetRestrictionLevel(c, RestrictionLevel.Low);
该方法 SetRestrictionLevelInternal
可从名为在的任何后裔类型(包括儿童
),但不能从的之外的类型本身调用。所以,你不能调用 SetRestrictionLevelInternal
在父
实例。在上面的例子中,我们选择暴露公共
方法,这反过来又调用保护
方法。
The method SetRestrictionLevelInternal
can be called from within any descendant type (including Child
), but cannot be invoked from outside the type itself. So, you cannot invoke SetRestrictionLevelInternal
on a Parent
instance. In the above example, we choose to expose a public
method, which in turn invokes the protected
method.
这篇关于做一个只读属性写在派生类中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!