简体   繁体   中英

C# How to add a property setter in derived class?

I have a requirement where I have a number of classes all derived from a single base class. The base class contains lists of child classes also derived from the same base class.

All classes need to be able to obtain specific values which may be obtained from the class itself -OR- it's parent depending on what the derived class is.

I looked at using Methods rather than properties however I also want to make the values available to a .NET reporting component which directly accesses exposed public properties in the reporting engine so this excludes the use of methods.

My question is what would be the 'best practices' method of implementing a setter in DerivedClass without having a publicly available setter in BaseClass

public class BaseClass
{
  private BaseClass _Parent;
  public virtual decimal Result
  {
    get { return ((_Parent != null) ? _Parent.Result : -1); } 
  }
}

public class DerivedClass : BaseClass
{
  private decimal _Result;
  public override decimal Result
  {
      get { return _Result; }
      // I can't use a setter here because there is no set method in the base class so this throws a build error
      //set { _Result = value;  }
  }
}

I can't add a protected setter (as follows) in BaseClass as I cannot change access modifiers in DerivedClass.

public class BaseClass
{
  private BaseClass _Parent;
  public virtual decimal Result {
    get { return ((_Parent != null) ? _Parent.Result : -1); } 
    protected set { }
  }
}

public class DerivedClass : BaseClass
{
  private decimal _Result;
  public override decimal Result
  {
    get { return _Result; }
    // This setter throws a build error because of a change of access modifiers.
    //set { _Result = value; }
  }
}

I don't want to add a member variable in BaseClass with a setter as I do not want the ability to set the property from the BaseClass or other classes that derive from base.

public class BaseClass
{
  private BaseClass _Parent;
  protected Decimal _Result; // This could result in a lot of unnecessary members in BaseClass.

  public virtual decimal Result {
    get { return _Result; } 
    // Empty setter ahead :) This does nothing.
    // I could also throw an exception here but then issues would not be found until runtime
    // and could cause confusion in the future with new developers etc.
    set { }
  }
}

public class DerivedClass : BaseClass
{
  public override decimal Result
  {
    get { return base.Result; }
    set { base._Result = value; }
  }
}

Other suggestions ?

You can use the 'new' keyword but this will replace property, what you want is not possible with override.

public class BaseClass
{
    private BaseClass _Parent;
    public virtual decimal Result
    {
        get { return ((_Parent != null) ? _Parent.Result : -1); }
    }
}

public class DerivedClass : BaseClass
{
    private decimal _Result;
    public new decimal Result
    {
        get { return _Result; }
        set { _Result = value;  }
    }
}

If you can add a protected setter in BaseClass you can use new keyword in in DerivedClass:

public class BaseClass  // ReadOnlyClass
{
    public int Value { get; protected set; }
}

public class DerivedClass : BaseClass
{
    public new int Value
    {
        get => base.Value;
        set => base.Value = value;
    }
}

I ended up changing the way I handled it and leaving the set in the base class however rather than having the base class getter / setter do nothing I threw a NotImplemented / NotSupported exception.

public class BaseClass
{
  private BaseClass _Parent;
  public virtual decimal Result
  {
     get
     {
      if (Parent == null)
        throw new NotImplementedException("Result property not valid");

      return Parent.Result;
    }
    set
    {
      throw new NotSupportedException("Result property cannot be set here");
    }
  }
}

public class DerivedClass : BaseClass
{
  private decimal _Result;
  public override decimal Result
  {
    get { return _Result; }
    set { _Result = value;  }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM