modifying access permissions from an abstract class in the derived class [duplicate] - c#

This question already has answers here:
Adding a set accessor to a property in a class that derives from an abstract class with only a get accessor
(3 answers)
Closed 9 years ago.
So I have an abstract class called AbstactSearchWithTwoLevelCache that was provided to me. All of its abstract properties only have read access (with a get;). I am not permitted to add a set; to the those abstract properties. Is there a way to change this in the derived class, SearchWithTwoLevelCache? In other words, is there a way to set these properties in the derived class?

If you mark the property with new, you define a new property, like this:
abstract class BaseClass
{
public int Property
{
get { ... }
}
}
class NewClass : BaseClass
{
public new int Property
{
get { return base.Property; }
set { ... }
}
}
EDIT:
The above works if the property in the base class is not abstract. When it is abstract, this will not work since you need to implement it. One option you do have is to create a class in between, like this:
abstract class BaseClass
{
public abstract int Property { get; }
}
class Between : BaseClass
{
public override int Property
{
get { ... }
}
}
class NewClass : Between
{
public new int Property
{
get { return base.Property; }
set { ... }
}
}
This however in no way is an elegant solution. Then, the real answer becomes that you cannot really do this (at least not without the above work around).

I can't imagine a way you can override them directly. Indirectly when you override the abstract class properties, the Getters can retrieve from a private field, and then you can create new properties that have Setters that set those fields.
Kind of a rig I know. Maybe there is a more elegant way around this.

Related

Prevent inherited member from accessing protected member

Is there a way in C# to prevent a derived class from inheriting a protected property?
class Base
{
protected int A { get; set; }
}
class DerivedA : Base
{
}
class DerivedB : DerivedA
{
}
What I want is for DerivedA to be able to access property A, however DerivedB should not. So is there a way to limit the inheritance of a property in the middle of the inheritance hierarcy?
Well, there is some valuable information in the comments, so I thought I'd better recap it so it will not get lost.
Kevin Gosse suggested to use the private protected access modifier.
The private protected keyword combination is a member access modifier. A private protected member is accessible by types derived from the containing class, but only within its containing assembly.
Please note that this access modifier is only available in c# 7.2 or higher.
While I agree with Kevin this might be a direct answer to your question, HimBromBeere suggested that this question is, in fact, an XYProblem - meaning you are asking how to implement a solution you are having problems with, instead of asking how to solve the underlying problem.
I also agree with him as well.
Fildor suggested using composition over inheritance - which is a very good point. using inheritance only for code reuse is a mistake. Remember that a derived class is a specific type of the base class type - for instance, a dog can derive from animal because a dog is a specific type of animal, but an airplane can't derive from a car just because they both have engines.
To get an answer to the actual underlying problem, I suggest you edit your question to include that problem, not only the current solution you are trying to implement, or perhaps ask a brand new question instead.
You should make it sealed:
class Base
{
protected int A { get; set; }
}
class DerivedA : Base
{
protected sealed override int A { get => base.A; set => base.A = value; }
}
class DerivedB : DerivedA
{
// Attempting to override A causes compiler error.
}
read more here: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed
Why would you want a class to not inheriting a protected property of its base class?
You should redesign your class model:
class Base
{
}
class BaseA : Base
{
protected int A { get; set; }
}
class Derived : Base
{
}
class DerivedA : BaseA
{
}

Access to member of abstract class

I have the following class hierarchy:
public abstract class BaseClass : IBaseInterface
{
public int PropertyA{
get
{
return this.propertyA;
}
set
{
this.propertyA = value;
// ... some additional processing ...
}
}
}
DerivedClassB : BaseClass
{
// some other fields
}
public class ContainingClassC
{
public IBaseInterface BaseInterfaceObjectD
{
get;
set;
}
}
Now, in order to access PropertyA of a DerivedClassB-Object (inherited from BaseClass), I have to cast the object to BaseClassA's ancestor, like so:
// This ContainingClassC is returned from a static, enum-like class:
// containingObject.PropertyA is DerivedClassB by default.
ContainingClassC containingObject = new ContainingClassC();
((IBaseInterface)containingObject.BaseInterfaceObjectD).PropertyA = 42;
Is there a way I can restructure these classes to do away with the cast? This code is part of a library, and my colleague wants me to get rid of the cast.
The goal is to simply write containingObject.BaseInterfaceObjectD.PropertyA = 42.
First of all in the line ((IBaseInterface)containingObject.BaseInterfaceObjectD).PropertyA = 42; you are casting the member to the same type that it is declared in, so the casting doesn't actually do anything.
To be able to access the PropertyA in the derived class - since you are casting it to an interface - the property must be declared in the interface and then implemented in the BaseClass.
public interface IBaseInterface{
int PropertyA{get;set;}
}
public abstract class BaseClass : IBaseInterface{
public int PropertyA{
get{ return this.propertyA;}
set {this.propertyA = value;}
}
}
As long as the interface is implemented properly, ProprtyA should be available in the base class, the derived class or with either of them cast'ed to the interface type.
If it's just a problem of the property not showing up in IntelliSense, then it might be a problem with your settings. Check out Options->Text Editor->C# and make sure you have IntelliSense turned on and not set to hiding anythig.

4 Classes with the same properties and methods - is it possible to create only one?

i have another question open here on SO and after thinking about it, i may be approaching this in the wrong way.
i have 4 classes, that have the same properties and methods.
some of the classes, have their own properties and methods ( not overrides of the existing ones ).
currently i create each class as:
public class ClassOne
{
public ClassOne()
{
}
public int ID {get;set;}
// More properties here
public void Set(){
// Do Stuff to save this
}
// More Methods here
}
cant i create one class that will generate all of the 4 classes?
and in the classes themselfs i only create specific properties/methods for that class?
repeating the code seems very odd to me, im sure there must be a way to do this, just dont know how.
Your situation is one of the main reasons why inheritance was invented. So with that, you can write
public class Base
{
// Properties and methods common to all
}
public class ClassOne : Base
{
// Properties and methods specific to ClassOne
}
public class ClassTwo : Base
{
// Properties and methods specific to ClassTwo
}
public class ClassThree : Base
{
// Properties and methods specific to ClassThree
}
public class ClassFour : Base
{
// Properties and methods specific to ClassFour
}
As requested, more code, using interfaces and abstract classes:
An interface is just a blueprint, defining what properties and methods are required to be compatible with other "BaseClasses"
public interface IBaseClass
{
public int ID {get;set;}
public void Set();
}
Abstract classes can contain code, but can not be instantiated, they are form of starting point for a class, but not a complete class themselves.
public abstract class ABaseClass : IBaseClass
{
public int ID {get;set;}
public void Set(){
// Do Stuff to save
}
}
Each class inherits from the abstract class and can then override and implement whatever it wants, customizing it however is necessary.
public class ClassOne : ABaseClass
{
}
public class ClassTwo : ABaseClass
{
}
public class ClassThree : ABaseClass
{
}
public class ClassFour : ABaseClass
{
}
ps. not entirely sure if my syntax is 100% correct
Could you simply make a base class with your properties and inherit from that class?
Why not use inheritance??
public class ClassOne
{
public ClassOne()
{
}
public virtual int ID {get;set;}
// More properties here
public virtual void Set(){
// Do Stuff to save this
}
// More Methods here }
public class ClassTwo : ClassOne
{
public string ClassTwoString { get; set; }
}
public class ClassThree : ClassOne
{
public string ClassThreeString { get; set; }
}
Can you make them all inherit off of the same class? If so, that sounds ideal.
Barring the possibility of making them inherit, you could write an interface that describes the methods and properties which each of them use. Then you can call each instance of the class through the same interface.
Barring again that possibility, you could write a reflective assignor/accessor. But you shouldn't do that.

C# Inheritance to hide inherited Members

I read other threads like this but they didn't work for me.
I got two classes:
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.
}
If I now create a new object of ClassB I get
_shouldBeInteger, _shouldBeBool, _shouldBeDateTime;
shouldBeInteger,shouldBeBool,shouldBeDateTime
But I want to hide the _variables to the User.
Setting them private in ClassB will override them, but I need to access them in order to parse there string values.
Update
There is a ClassC filling ClassAs' values, which mainly is the reason why they have to be writeable. There is no way for me to change the way that works, but I'm fully in Control of ClassA and ClassB
ClassC //not changeAble for me
{
//infomagic filling values of ClassA
}
Setting ClassA variables to private won't work, because programmer of ClassA produced it in a strange way.
Solution
Because ClassA needs to be writeable, but not readable to other classes than inheritated, I finally got this:
ClassA
{
public string _shouldBeInteger { protected get; set; }
//and so on
}
which causes ClassB to work with theese properties, without giving them outside.
Intellisense still shows them, but you might consider using:
[EditorBrowsable(EditorBrowsableState.Never)]
to solve that.
Thanks to all.
I think you can solve your problem using:
public class ClassA
{
protected string _shouldBeInteger;
protected string _shouldBeBool;
protected string _shouldBeDateTime;
}
so those variables are accessible to derived classes but not to user.
EDITED after user update:
I don't know if this could be a vali solution for you, but try:
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); }
}
}
Inheritance can't hide the members as you would think. The new modifier exists to "hide" a base member, but that doesn't play nice when talking to base types.
http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
You can either change the access level of the fields (the preferred way) or you can wrap the class instead of inheriting from it and provide simple pass-through methods to delegate to the wrapped class. This is called the Adapter Pattern:
public class ClassB
{
private ClassA _wrappedClass;
}
Just as an aside, your public fields are following the naming convention commonly used for private fields.
The required access level for derived classes is protected. If the members are used publicly but in the same assembly you can use protected internal. If the members are used publicly by other assemblies... I'd suggest refactoring.
The problem is that you declared the fields public in the base class. In order not to violate the polymorphic nature of inheritance, anything public in the base class must be public in all derived classes as well. If you could change that, you could never be sure that a ClassB could be passed to something expecting a ClassA.
Therefore, as other people have suggested, you probably want the base class fields to be declared protected, which is like private except derived classes can see them.
However if you do need to access them via an actual instance of ClassA, you could declare them private and give them virtual public properties which the derived class can then override. This at least allows the derived class to change their behaviour, but it still can't actually hide them.
If that also doesn't fit, then it's probably worth considering using composition instead of inheritance because the substitution principle is actually getting in your way, and that's an inheritance fundamental.
If you don't have control over ClassA, you'll need to create a wrapper/adapter class like so:
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; }
}
}
OR
public class ClassB
{
public int ShouldBeInteger{ get; set; }
}
In both of this case ShouldBeInteger will be accesible outside the class.
In first case there were a private field, which cannot be accesible outside the class,
values to private filed can be set through the public field.
In second case the compiler automatically create a private backing field and do the same
process as above. This is auto implemented property.
Hope this may help you.

C#: Semi-Abstract Automatic Properties?

In a base class, I want to define an abstract get, but at that point, I don't care about the set. How can I define a setter in my child class?
I tried a few things, but I can't get it to work. For example I tried :
public class BaseClass
{
public abstract bool MyBool { get; }
}
public class ChildClass : BaseClass
{
public override bool MyBool { get; protected set;}
}
And :
public class BaseClass
{
public bool MyBool { abstract get; }
}
public class ChildClass : BaseClass
{
public bool MyBool { override get; protected set;}
}
I know I can workaround this by not using automatic properties in the child class and directly setting the underlying field instead of creating a setter, but I'm looking for something better.
Edit: I don't want to add an abstract setter in the BaseClass.
It may make more sense to use an interface rather than a base class. Then you simply have the classes that need to provide that property implement that interface.
For instance, you can create this interface:
public interface IBoolable {
bool MyBool { get; }
}
Then it is still valid to implement the interface like so:
public class BoolableItem : IBoolable {
public bool MyBool { get; protected set; }
}
Done this way, your code can safely assume anything that implements IBoolable has a property called MyBool that is at minimum read-only.
One solution is to make MyProperty not abstract but delegate its implementation to an abstract protected property that children must override:
public abstract class BaseClass
{
public bool MyBool { get { return MyBoolInternal; } }
protected abstract bool MyBoolInternal { get; set; }
}
public class ChildClass : BaseClass
{
protected override bool MyBoolInternal { get; set; }
}
You have to make up your mind what behavior you want: if it is defined as abstract then a deriving class MUST implement it.
So what you should do is this:
public abstract class BaseClass
{
public abstract string MyProperty { get; set; }
}
public class DerivedClass : BaseClass
{
public override string MyProperty
{
get { return "myValue"; }
set { /* do nothing, not applicable for this class */ }
}
}
Don't throw the NotImplementedException - that is not what you want, you simply want the setter to do nothing for some child classes.
To leave it ambiguous whether you want a setter in inherited classes would violate OOP principles--that is, if a class (abstract or not) has a public/protected setter (abstract or not), then all inheriting classes must also; if a class does not, then inheriting classes must not.
Another way to think about this is to consider properties such that read-only or read-write is part of the contract of the class. Since instances of inheriting classes must adhere to an "Is-a relationship" (the LSP), inheriting classes cannot "add a setter" where the main class didn't have one, because the fact that the main class had a property without as setter is part of the main class definition. In effect, since the main class cannot change the property in question via a setter, therefore all inheriting classes MUST guarantee the same behavior.
Consider using a protected backing field; then you can split this property into a read-only property and a separate setter method. Then, the main class can have the property only and the subclass can have a setter method that the main class doesn't know about. However, I'm not sure this would be a good design either.

Categories

Resources