The name of this type of semantic inheritance

public class _base { protected int x = 5; protected int GetX(_base b) { return bx; } } public class _derived : _base { public int Foo() { var b = new _base(); //return bx; // <-- this would be illegal return GetX(b); // <-- This works and does exactly the same as the line above } } 

(Please do not change the code. It works and shows the problem.)

Error

 Cannot access protected member '_base.x' via a qualifier of type '_base'; the qualifier must be of type '_derived' (or derived from it) 

Please note that since b is of type _base and we are not in the database, we cannot access protected members. I suppose the reason is that _base may be of a different derived type and therefore does not protect the code, but that is not the point. What I am doing is creating work for the above problem using additional protected methods. It gives me the behavior I want and the protection I want. I am sorry that there was no keyword that allows this curious access, but it is not. I am wondering if this "template" has a name.

(I use protected because internal allows anyone in the same assembly access)

+4
source share
4 answers

As a rule, this type of access is not allowed, since access modifiers work with classes (as meta-access attributes). In your derived class, an instance of your base class is not related to the derived class. Here we mix instances and classes. The protected keyword only offers access to derived classes, but from any instance (even if in a derived class).

This is clearly a deficit in the language, but since 99.9% of the time it is not used, it is not needed. In any case, in C # there is no keyword suggesting what you want.

+3
source

UPDATE: rewriting this answer since the question has been rewritten.

I do not know a single name for the template that you illustrated.

As you might imagine, the reason why it is illegal to access a field is because we do not know that instance b is an instance of _derived. β€œsecure” access means that _derived only allowed access to the protected members of _derived instances ; he is not allowed access to the protected members of "SomeOtherType" instances, which also derives from _base.

Now, if the question really is "is there a way to directly access member x from each derived class through any instance?" then yes. You reject the obvious decision to make it internal. (*) There is another way. Do it:

 abstract class B { private B() {} private int x; private class D1 : B { } private class D2 : B { } public static B MakeD1() { return new D1(); } public static B MakeD2() { return new D2(); } } 

Now methods B and methods of derived classes D1 and D2 can directly access this.x , but methods of other types cannot do this. There are no other derived types except D1 and D2; cannot be, because the only constructor of B is private. And there cannot be any instances of B that are not D1 or D2, because they are abstract.


(*) Remember that if you make it internal, then you only need to worry about you turning to your member. Including code in a code review if they do something offensive to a member is a perfectly acceptable solution.

+2
source

Sealing.

http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming )

Basically you control who has access to members through an accessory ("setters" and "getters"). How the underlying data lies, it remains hidden to the user.

Think about it:

If you want to rename your X variable (for whatever reason) to your base class, but there are 100 classes derived from this base class that accessed it directly.

You break this code.

 class derived { void DoSomething() { x += 1; } // x renamed, doesn't compile anymore } 

Now, with encapsulation, since x cannot access directly, we have accessors:

 class derived { void DoSomething() { SetX(GetX() + 1); } // No prob! } 
0
source

I think I understand what you mean. Do not instantiate the base class in methods. It is created by the constructor. Base members of a base class that use only the member name or your case precede the keyword.

In the above example, you would use it as follows:

 class A : _base { void Foo() { x = 10; //or base.x = 10; SetX(10); //or base.SetX(10); Console.WriteLine(GetX()); //or base.GetX() } } 

Also, you may be interested in Properties , which is a good syntactic sugar for ugly getX java and setX pattern.

0
source

Source: https://habr.com/ru/post/1336086/


All Articles