c# – 在派生类中创建一个只读属性

前端之家收集整理的这篇文章主要介绍了c# – 在派生类中创建一个只读属性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想要实现的目标如下:
我在BaseClass中声明了一个属性.如果通过基类’指针访问此属性,则只有getter可用,但如果使用派生类指针,我希望能够获取并设置该属性.所以intellisense甚至不应该显示基本指针的setter.
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;}
     }
}

一个现实的例子:
考虑一种情况,即您拥有从Person类派生的Parent和Child类.想象一下属性-RestrictionLevel,两者都可以读取它,但只有父级可以设置值.有没有更好的方法来设计这种情况?

解决方法

我能想到的唯一方法是用新的方式遮蔽房产:
public class DerivedClass : BaseClass
{
    int intValue;

    public new int MyProperty
    {
        get { return intValue; }
        set { intValue = value; }
    }
}

注意如何将属性声明为new而不是override.当然,这意味着DerivedClass类型的MyProperty与BaseClass类型的MyProperty无关,它是一个全新的属性,恰好具有相同的名称(因此将其隐藏在基类中).

结果是这样的:

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在评论中所述:

(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完成).例如,请考虑以下事项:

DerivedClass d = new DerivedClass();
d.MyProperty = 42;

BaseClass b = d;
Console.WriteLine(b.MyProperty);  // prints 1

也就是说,使用new时我总觉得有点脏(当我想到它时,我不确定我是否真的在生产代码中完成了).

更新
鉴于您给出的示例场景(我以一种方式解释父级是否能够设置子级的RestrictionLevel),它可以像这样解决

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);
    }
}

这意味着以下代码有效:

Child c = new Child();
Parent p = new Parent();
p.SetRestrictionLevel(c,RestrictionLevel.Grounded);

……但这个不是:

Child c = new Child();
c.SetRestrictionLevel(c,RestrictionLevel.Low);

方法SetRestrictionLevelInternal可以从任何后代类型(包括Child)中调用,但不能从类型本身外部调用.因此,您无法在Parent实例上调用SetRestrictionLevelInternal.在上面的示例中,我们选择公开一个公共方法,该方法调用受保护的方法.

原文链接:https://www.f2er.com/csharp/96428.html

猜你在找的C#相关文章