protected internal class working within class but not working outside - c#

I was trying few things and would like to know why this is happening so.
Say, I have a class called A in namespace n and I was trying to create protected internal class B.
namespace n
{
public class A
{
public A()
{
}
}
protected internal class B //throwing error
{
}
}
But when i try like this (B as a sub class of A), its not throwing error and its built success. Could you explain me why it is so?
namespace n
{
public class A
{
public A()
{
}
protected internal class B // its not throwing error
{
}
}
}
Am i missing anything theoretically? Its quite a bit confusing.

A class can't be protected except when it is inside another class.
The protected keyword is only valid for members of a class. In your second example, class B happens to be that member.
Think about it:
protected means: Derived classes can access this member.
As there is no such concept as derived namespaces, the protected keyword doesn't make sense for members of a namespace.

Look at the error.
Elements defined in a namespace cannot be explicitly declared as
private, protected, or protected internal
Only internal or public members are allowed outside the class.
Your second case is defining the class B as member of class A that is why you are not getting the error.
You may see Access Modifiers C#
Classes and structs that are declared directly within a namespace (in
other words, that are not nested within other classes or structs) can
be either public or internal. Internal is the default if no access
modifier is specified.

protected declares visiblity level for derived types.
In your first case you declare class inside namespace. There is no any polymophic support for namespaces, so there is no any sence of using protected classes in namespace
In second case, instead, you use it inside other classe (class A), which make it visible for all children of A class.

Related

Why member access modifier does matter for nameof()?

I'm a little bit confused with nameof() operator. So for example I can't use class's private fields in nameof() in another class, but I can use public non static fields using non static property, so I don't need instantiated object.
Is it consistently? Why member access modifier does matter for nameof()?
class A
{
private int X;
public int Y;
public A()
{
var x = nameof(A.X);//OK
var y = nameof(A.Y);//OK
}
}
class B
{
public B()
{
var x = nameof(A.X);//Compilation error
var y = nameof(A.Y);//OK
}
}
The purpose of access modifiers like private is to hide the implementation details. They are saying "Nope, you don't need to know this. This is implementation detail". That's why nameof is not allowed to access private properties. Whatever class you are in, that class should not know about the implementation details of some other class.
Static vs non-static is different. Its purpose is not to hide something that you don't need to know about. Its purpose is just to distinguish between members that belongs to instances of the class and members that belongs to the class itself. All you want here is just the name of that member, which requires no instances to be created, so why disallow you? Note that the member is accessible i.e. it's not something you shouldn't know about.
Field X in class A is private. door is locked, you cant access it no matter what you do.
This is not a nameof problem, its Access Modifier problem
Access Modifiers (C# Programming Guide)
All types and type members have an accessibility level, which controls
whether they can be used from other code in your assembly or other
assemblies. You can use the following access modifiers to specify the
accessibility of a type or member when you declare it:
and
public The type or member can be accessed by any other code in the same assembly or another assembly that references it.
private
The type or member can be accessed only by code in the same class or struct.
protected The type or member can be accessed only by code in the same class, or in a class that is derived from that class. internal
The type or member can be accessed by any code in the same assembly,
but not from another assembly.
protected internal The type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class
in another assembly.
private protected The type or member can be accessed only within its declaring assembly, by code in the same class or in a type that is
derived from that class.
Not a direct answer to your question, but I usually get around this but using a static helper class:
class A
{
public static class Properties
{
public const string X = nameof(A.X);
}
private string X { get; }
}
Then using
A.Properties.X
It's a little bit more verbose, but still enables refactoring tools to work effectively.

How to force a namespace member to be visible only to members of its direct containing namespace in C#?

Consider the following code:
using System;
namespace Nesting
{
class Program
{
static void Main()
{
new Nested.Class().Method();
}
}
namespace Nested
{
internal class Class
{
internal void Method()
{
Console.WriteLine("Inside Method");
}
}
}
}
The output:
Inside Method
Which means that Nesting members are allowed to access internal members of Nested. Is there a way to force members of Nested to be visible only to other Nested members?
In short, Not within the same assembly.
Unlike Java, the internal accessibility (Friend in VB.Net) is to make the class/member only visible within the same assembly.
Strictly speaking the using reflection, you could still get to the hidden bits in another assembly.
An alternate scenario would be to use nested classes (rather than namespaces), so something like:
internal class Nested
{
protected class Class
{
// Only usable from the Nested class
internal void Method()
{
Console.WriteLine("Inside Method");
}
}
}
}
No, you can't. All three relevant access modifiers don't give what you want. There is no way to enforce this without pulling the nested class to another assembly.

Protected function not accessible in derived class

I am making a simple C# console application to test inheritance but when I add 2 new classes and inherit one with another ( Mammal:Animal ) and make an object of mammal in the Program.cs class i-e
Program.cs
Mammal mam = new Mammal();
mam.see(only public function are showing of animal not the protected member of function)
Animal.cs
class Animal
{
protected void check()
{}
public void see()
{}
}
Mammal.cs
class Mammal:Animal
{
public void hair()
{}
}
Can't figure out why it is not allowing, as protected allows to inherit if they are in its hierarchy.
The code within Mammals has access to protected members of Animals, but only via an expression of type Mammals or a subtype.
From outside the class - which I assume this is - there's no access to protected members.
From section 3.5.3 of the C# 5 specification (emphasis mine):
When a protected instance member is accessed outside the program text of the class in which it is declared, and when a protected internal instance member is accessed outside the program text of the program in which it is declared, the access must take place within a class declaration that derives from the class in which it is declared. Furthermore, the access is required to take place through an instance of that derived class type or a class type constructed from it.
(As noted by Jonathan Reinhart, you almost certainly want these types to be called Mammal and Animal, by the way.)
Below is the way to access protected methods in derived class
class Animal
{
protected void check()
{}
public void see()
{}
}
class Mammal:Animal
{
public void CallSee()
{
Animal obja = new Animal();
obja.see();
}
}
Now you can create instance of class Mammal and call method callSee which will in turn call see method of Animal. As above answer suggestion proctected members are not accesible outside derived class. It can only be accessible in derived class
In Main Function write below code.
Static Main()
{
Mammal objm= new Mammal();
objm.CallSee();
}
The protected access modifier can be accessed only from within the declaring class or its sub classes...only public and internal makes a method accessible from outside

Am I trying to Implement Multiple Inheritance. How can I do this

I have created a class say A which has some functions defined as protected.
Now Class B inherits A and class C inherits B. Class A has private default constructor and protected parameterized constructor.
I want Class B to be able to access all the protected functions defined in Class A but class C can have access on some of the functions only not all the functions and class C is inheriting class B.
How can I restrict access to some of the functions of Class A from Class C ?
EDIT:
namespace Db
{
public class A
{
private A(){}
protected A(string con){assign this value}
protected DataTable getTable(){return Table;}
protected Sqlparameters setParameters(){return parameter;}
}
}
namespace Data
{
public class B:A
{
protected B():base("constring"){}
protected DataTable output(){return getTable();}
protected sqlparameter values(param IDataParameter[] parameter){}
}
}
namespace Bsns
{
public class C:B
{
protected C():base(){}
protected DataTable show()
{return values(setparameter());}
}
}
EDIT
I think what I am trying to do here is Multiple inheritance.
Please check.
class A
{
//suppose 10 functions are declared
}
class B:A
{
//5 functions declared which are using A's function in internal body
}
class C:B
{
//using all functions of B but require only 4 functions of A to be accessible by C.
}
You need to have classes A and B in the same assembly and class C in another assembly. You can mark the member you want to restrict access to by derived classes as protected internal. This makes the member, well, protected and internal. As far as limiting class C's access to the member it will suffice to mark it internal. Since this will make it it public within the first assembly, you might want to add protected to enforce encapsulation.
Turns out marking a member protected internal doesn't make it private to classes outside of the assembly. Seems that for all intents and purposes protected internal is the same as protected. Unfortunately the only way I can see achieving this would be to mark it internal and put up with the member being public to the defining assembly.
Even C# programming guide on MSDN gets it wrong:
By combining the protected and
internal keywords, a class member can
be marked protected internal — only
derived types or types within the same
assembly can access that member.
Phil Haack explains:
protected internal means protected OR
internal
It’s very clear when you think of the
keywords as the union of accessibility
rather than the intersection. Thus
protected interna means the method is
accessible by anything that can access
the protected method UNION with
anything that can access the internal
method.
Here is the updated code:
class A {
protected void Test3(){} //available to subclasses of A in any assembly
protected internal void Test() { } //Same as protected :(
public void Test2(){}//available to everyone
internal void Test4(){} //available to any class in A's assembly
}
class B : A {
void TestA() {
Test(); //OK
}
}
//Different assembly
class C : B {
void TestA() {
Test4(); //error CS0103: The name 'Test4' does not exist in the current context
}
}
It looks like you should probably using Composition not Inheritance.
Class A implements calc() and allow().
Class B has a private A but isn't derived from A
Class C derives from B and has no access to the private A object in class B.
I'd suggest that you rethink your design. Maybe there is a simpler way. What if C uses an instance of B instead of deriving from it (composition) ? That way C can use B's public methods but not get access to the protected ones.
Class A should not care about the level/depth of a descendant. If something is marked protected, it should be protected for both B and C (regardless of the depth of the inheritance chain).
B may choose to delimit its descendants by tightening the constraints (but this is rare).
If you can tell me more about your context - the problem you are trying to solve.. I can give you a more detailed/useful answer.
As others have said, you probably want to use composition instead of inheritance.
class A {
protected void Foo() { … }
protected int Bar() { … }
}
class B {
private A a;
public B() {
this.a = new A();
}
protected int Bar() {
return a.Bar();
}
}
class C : B { … }
Looking at your example, though, I would question whether C should inherit from B, or whether it should really just hold a reference to an object of type B.
Personally, I wouldn't go putting classes in different assemblies just for the purpose of restricting access if the class doesn't otherwise logically belong in a different assembly. There are other ways to handle it.

Why does FxCop treat protected as public?

Why does FxCop treat protected members as if they are public throwing DoNotDeclareVisibleInstanceFields error? I'm pretty sure protected members is a valid code design.
It's telling you not to declare fields which are visible outside the class, i.e. not private. In this case it is correctly recognising the protected modifier as exposing the members outside the class, albeit only to derived types.
I'm not sure if that's what you meant, but in general protected members are part of a class' interface.
You don't want public member variables because they make your implementation inflexible. Protected member variables do the same since classes that inherit from yours will depend on them, thus making your implementation inflexible.
Asaf
It looks like the error you're getting is flagging your externally visible instance fields. The recommended practice here is to make this field private and expose it through an externally visible property (with a public or protected access modifier).
The MSDN page on the error gives a good example:
using System;
namespace DesignLibrary
{
public class BadPublicInstanceFields
{
// Violates rule DoNotDeclareVisibleInstanceFields.
public int instanceData = 32;
}
public class GoodPublicInstanceFields
{
private int instanceData = 32;
public int InstanceData
{
get { return instanceData; }
set { instanceData = value ; }
}
}
}

Categories

Resources