做一个只读属性写在派生类中 [英] Make a read only property writable in the derived class

查看:110
本文介绍了做一个只读属性写在派生类中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现的是以下内容:
我都在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆