If class declare as a Private and its Members are Public so what is the accessibility of related class?
If your private class implements some interface you can access to public methods via the interface. Here's piece of code:
public interface ITest
{
void Test();
}
public class Program
{
public static void Main()
{
ITest nestedProgram = new NestedProgram();
AnyOtherClass otherClass = new AnyOtherClass();
otherClass.AnyMethod(nestedProgram);
}
private class NestedProgram : ITest
{
public void Test()
{
Console.WriteLine("Test method invoked");
}
}
}
public class AnyOtherClass
{
// won't compile
// public void AnyMethod(Program.NestedProgram test)
public void AnyMethod(ITest test)
{
// won't compile
//ITest nestedProgram = new Program.NestedProgram();
test.Test();
}
}
The class is what you declare it as. The "private" modifier on the class declaration matters on nested classes, but there's nothing to stop the class its nested in using its public members. I would argue that the two aren't particularly related because their goals are slightly different (one is the visibility of the class itself for instantiation and where it can be referenced, the other controls what members can be accessed).
Also consider this example:
public interface ITest
{
void TestMethod();
}
public static class TestFactory
{
private class Test: ITest
{
public void TestMethod() { }
}
public static ITest CreateTest()
{
return new Test();
}
}
Examples:
TestFactory.Test a = new TestFactory.Test(); // doesn't work because the class is private
TestFactory.Test b = null; // also doesn't work because the class is private
ITest c = null; // works, the interface is public
ITest d = TestFactory.CreateTest(); // works, because the interface is public and CreateTest is declared to return the interface.
In this example, only TestFactory can see the class to create an instance of it. On the other hand, the return value is the public interface, which states that implementers should have a public method TestMethod();
In this situation, the method has to be public. Although only TestFactory can directly instantiate and see the class, it can still be exposed through an interface (or base class).
Anyway, it's probably best to take a look at the docs.
Access modifiers are keywords used to specify the declared accessibility of a member or a type.
public modifier
The public keyword is an access modifier for types and type members. Public access is the most permissive access level.
There are no restrictions on accessing public members.
Accessibility
Can be accessed by objects of the class
Can be accessed by derived classes
Private access is the least permissive access level.
Private members are accessible only within the body of the class or the struct in which they are declared.
Accessibility
Cannot be accessed by object.
Cannot be accessed by derived classes.
Now lets come to the exact answer if the class is declared as private and its members are public then accessibility level of members will stay within class because private class can't be inherited.
Related
Say I have a generic class Foo, that has a variable that is protected
public class Foo<T>
{
protected bool knowsFu;
}
I also have 2 sub-classes: Bar and Pipe
public class Bar : Foo<Bar> {}
public class Pipe : Foo<Pipe> {}
It is actually possible for me to access the knowsFu in Pipe FROM Bar, e.g.:
public class Bar : Foo<Bar>
{
void UpdateFuInOtherClass(Pipe p)
{
p.knowsFu = false;
}
}
Is this intended behaviour? (If so, what would be the usecase?)
Is there a way for me to prevent other Foo-Subclasses from modifying/reaching the protected variable inside of my current subclass?
More specifically: I'm using a generic class to implement the Singleton-Pattern:
https://en.wikipedia.org/wiki/Singleton_pattern
However, I'm currently able to access any singleton's protected instance-variable, as long as I am inside of another Singleton. Is there a way to prevent this?
EDIT: It might be relevant to note that the protected variable (knowsFu) is actually STATIC as well.
EDIT2: Ok, maybe the example was abit too generic.. here's how I'm actually currently implementing it:
why use Singleton? A:The platform I'm working on is Unity3D, in which the pattern is used frequently
I have a generically typed abstract class SingletonBehaviour
public abstract class SingletonBehaviour<T> where T : MonoBehaviour
{
public static T Instance { get { return instance; } }
protected static T instance { get; private set; } }
// Loading is done through Unitys Awake-Method
}
One of the Singleton-Objects that I'm using is the APIManager
public class APIManager : SingletonBehaviour<APIManager>
{
// Methods like SendHTTPPost(), HTTPGet(), etc.
}
However, since most of my projects need some better API-implementation than that, what I'm currently doing is:
public class ProjectAAPIManager : APIManager
{
// Overriding Instance so my return value is not APIManager but instead ProjectAAPIManager
public static new ProjectAAPIMamager Instance { get { return (ProjectAAPIManager)instance; } }
}
This ^ is the reason my (inner) instance-variable is protected, and not private.
However, because of this, any other SingletonBehaviour in my project can now access the (inner) instance-variable on my ProjectAAPIManager
public class GameController : SingletonBehaviour<GameController>
{
private void AMethod()
{
// Accessing inner variable instead of public one
ProjectAAPIManager.instance.DoSomething();
}
}
As it's only the getter, this currently does not really matter. But what if I'd need access to the setter in my subclass as well?
Also: would it be worth it to generically type my APIManager as well?
Your question is nothing short of bewildering. How can you make a protected member not be accesible from a derived class? Well, a good start is not making it protected.
protected is by definition exactly what you don't want, so don't use it! Use private instead.
If what you are asking is how to make it a readonly member when accessed from derived types, you have two options:
Declare it as readonly in the base class if possible.
Use a protected property instead with a private setter.
Many novice coders seems to think protected members aren't part of the public surface of the type but they really are, as long as the class can be extended. As such, the rules of public members apply: never expose public fields unless they are readonly or constants, use properties instead.
You should not have classes that implement your generic singleton class.
Otherwise, by default, your protected fields will be accessible by the subclasses (it's what "protected" keyword does)
Instead, you should do something like this:
class Program
{
static void Main(string[] args)
{
var barInstance = Foo<Bar>.GetInstance();
}
}
public class Foo<T> where T : new()
{
protected bool knowsFu;
private static T _instance;
public static T GetInstance()
{
if (_instance == null)
_instance = new T();
return _instance;
}
}
public class Bar
{
public Bar()
{
}
}
Edit 1:
To use a singleton, you should not make another class implement the singleton behavior (This is not how the singleton pattern works).
To use the same classes as your second example, you should do something like this.
public class SingletonBehaviour<T> where T : new()
{
public static T Instance
{
get
{
if(instance == null)
instance = new T()
return instance;
}
}
private static T instance { get; set; }
}
public class APIManager // This class should not inherit from the SingletonBehavior class
{
// Methods like SendHTTPPost(), HTTPGet(), etc.
}
public class ProjectAAPIManager : APIManager
{
public ProjectAAPIManager GetInstance() => SingletonBehavior<ProjectAAPIManager>.Instance();
}
This question already has answers here:
How to Mock the Internal Method of a class?
(6 answers)
Closed 4 years ago.
The Situation
Suppose I have a class with an internal method:
class MyClass : IMyClass
{
public void PublicMethod() { ... }
internal void InternalMethod() { ... }
}
that implements an interface:
interface IMyClass
{
void PublicMethod() { ... }
}
And a container class that holds an instance of MyClass and other concrete classes:
class ContainerClass
{
public MyClass myClass;
...
}
ContainerClass is used by various assemblies. When used within the same assembly as MyClass the calling method can invoke containerClass.myClass.InternalMethod()
The Problem
In an effort to make things more easily mockable for testing, I am now trying to replace the ContainerClass's properties with interfaces rather than concrete classes, e.g.:
class ContainerClass
{
public IMyClass myClass;
...
}
But, if I do that, InternalMethod can no longer be invoked using containerClass.myClass.InternalMethod() because the method doesn't exist on the interface... nor can it, because it is internal. However, I cannot make the interface internal because ContainerClass is used by other assemblies as well.
Let's assume that I cannot change the internal access to that method. Is there another way?
EDIT: This is different from How to Mock the Internal Method of a class? because I am not trying to mock the internal method, I am trying to keep it exposed when replacing a concrete class (MyClass) with an interface (IMyClass).
An option is to create two interfaces, one public and one internal:
public interface IMyClassPublic
{
void PublicMethod();
}
internal interface IMyClassInternal
{
void InternalMethod();
}
Implement both of them in MyClass (you need to implement IMyClassInternal explicitly since it's internal):
public class MyClass : IMyClassPublic, IMyClassInternal
{
public void PublicMethod() { }
void IMyClassInternal.InternalMethod() { }
}
And change ContainerClass so that it exposes both interfaces separately (and probably make myClass private):
public class ContainerClass
{
private MyClass myClass;
public IMyClassPublic myClassPublic
{
get
{
return myClass;
}
}
internal IMyClassInternal myClassInternal
{
get
{
return myClass;
}
}
}
Now you can mock both of them, use the internal method as containerClass.myClassInternal.InternalMethod() and the public method as containerClass.myClassPublic.PublicMethod().
I Am getting a warning message in my class, like
Add a Protected constructor or the static keyword to the class declaration
Solution
The error is gone after I tried both the below ways,
static class without constructor
public static class Program {
}
Non static class with protected using constructor
public class Program
{
protected Program() { }
}
Question:
So What is the difference between Static Class vs Protected Constructor which is mentioned in my above solution? And which one is best to use?
A static class doesn't need an instance to access its members. A static class cannot have instance members (e.g. public int MyNumber; is not allowed on a static class because only static members are allowed on a static class). Both instance and static members are allowed on a non-static class though. A class with a protected constructor can only have an instance created by itself or something that inherits from it.
public class Program
{
protected Program()
{
// Do something.
}
public static Program Create()
{
// 100% Allowed.
return new Program();
}
public void DoSomething()
{
}
}
public static class AnotherClass
{
public static Program CreateProgram()
{
// Not allowed since Program's constructor is protected.
return new Program();
}
}
public class SubProgram : Program
{
protected SubProgram()
{
// Calls Program() then SubProgram().
}
public new static Program Create()
{
// return new Program(); // We would need to move the SubProgram class INSIDE the Program class in order for this line to work.
return new SubProgram();
}
}
Program.Create(); // Can be called since Create is public and static function.
Program.DoSomething() // Can't be called because an instance has not been instantiated.
var test = Program.Create();
test.DoSomething(); // Can be called since there is now an instance of Program (i.e. 'test').
AnotherClass.CreateProgram(); // Can't be called since Program's constructor is protected.
SubProgram.Create(); // Can be called since SubProgram inherits from Program.
As for performance, this distinction doesn't really have much to do with performance.
You probably only have static members in the class and the code analyser assumes that your intention is to not be able to create instances of the class so it is asking you to either make the class static
public static class Program {
//...static members
}
or put a protected/private constructor
public class Program {
protected Program { //OR private
}
//...static members
}
to prevent instances of that class from being initialized.
A static class is basically the same as a non-static class, but there is one difference: a static class cannot be instantiated.
Reference Static Classes and Static Class Members (C# Programming Guide)
The protected constructor means that only derived classes can call the constructor
and a private constructor wont allow any other classes to initialize the class with a private constructor
A static constructor is called when the class type is instantiated. The protected constructor is called when an instance of a class is created. The protected part means only classes that inherit the class can call it.
Static Constructor: Called once when the class type is instantiated and is used to initialize static members. Does not create an instance of the class.
Protected Constructor: A constructor that can be called only by the class or a class that inherits it.
The best practices for this is that you should have a static constructor for initializing static members and a protected constructor if you only want classes that inherit to be able to create an instance of your class. You can have both.
public class MyClass
{
static readonly long _someStaticMember;
private bool _param;
static MyClass()
{
//Do Some Logic
_someStaticMember = SomeValueCalculated;
}
protected MyClass(bool param)
{
_param = param;
}
}
public class ChildClass: MyClass
{
public ChildClass(bool param) : base(param);
}
public class NotChildClass
{
public MyClass someObject = new MyClass(true); //Will Fail
}
I am trying to figure out a way I can make use of private static fields in a generic class. This is the obvious way to do it (fiddle). It won't compile because Field is not accessible in BaseChild, and ideally I wouldn't want it to be accessible there:
public class Base<T>
{
private static readonly string Field = "field";
public Base()
{
Console.WriteLine(Field);
}
}
public class BaseChild : Base<string>
{
public BaseChild()
{
Console.WriteLine(Field);
}
}
The problem with this solution is that there is a different Field for each generic type, instead of being shared across them.
I have seen this answer where it says that JetBrains recommends a solution for static fields across generic types:
If you need to have a static field shared between instances with different generic arguments, define a non-generic base class to store your static members, then set your generic type to inherit from this type.
This makes sense for the case where you have public or protected static fields in the base class that you want to share across any child class like this example (fiddle):
public abstract class Base
{
protected static readonly string Field = "field";
}
public class Base<T> : Base
{
public Base()
{
Console.WriteLine(Field);
}
}
public class BaseChild : Base<string>
{
public BaseChild()
{
Console.WriteLine(Field);
}
}
However, what about the case where you want to use a private static field? I would guess that this is not possible since private means only accessible to the class it's declared in and I think that since the generic class is really just a template to create a class, that any private field could only ever be shared by each class, not across all the classes created by the template.
Do I have to just put the private field in the generic class (example 1) and accept it as at least a workable solution for what I want, or is there another way I can accomplish this?
First off -- private is doing exactly what it's made to do: to restrict access to only the type it was declared in. Keep in mind that instantiations of a generic type are all distinct types. You shouldn't be wanting to work around this.
If I understand your question correctly, you can accomplish what you want by using protected with an extra level of inheritance:
class EvenMoreBase
{
protected static readonly string Field = "field";
}
class Base<T> : EvenMoreBase
{
public Base()
{
Console.WriteLine(Field);
}
}
class BaseChild : Base<string>
{
public BaseChild()
{
Console.WriteLine(Field);
}
}
Now each of your Base<T> will share the same instance of Field.
You're correct in your thoughts on private within the base class. Whether it is static or not makes no difference.
Here's a little example:
using System;
public class Program
{
public static void Main()
{
Bar b = new Bar(); // Prints "Foo"
// Console.WriteLine(Foo.BaseField); // Compile error
}
}
public class Foo
{
protected static readonly string BaseeField = "Foo";
}
public class Bar : Foo
{
public Bar()
{
Console.WriteLine(Foo.BaseeField);
}
}
Marking it protected is useful, if you'd like only your children to be able to access it. And leaving it static is how you'd keep only one instance around for all children of the base Foo class.
This is something I came up with that I think actually does what I want better than the initial example I put in my question. It shares a single static field across all the generic types, and it is inaccessible from children of the Base generic class.
public static class Base
{
private static string Field = "field";
public class Base2<T>
{
public Base2()
{
// Field is accessible here, but is the same across all generic classes
Console.WriteLine(Field);
}
}
}
public class BaseChild : Base.Base2<string>
{
public BaseChild()
{
//Field is not accessible here, and I don't really want it to be
//Console.WriteLine(Field);
}
}
This question is similar to c# internal abstract class, how to hide usage outside but my motiviation is different. Here is the scenario
I started with the following:
internal class InternalTypeA {...}
public class PublicClass
{
private readonly InternalTypeA _fieldA;
...
}
The above compiles fine. But then I decided that I should extract a base class and tried to write the following:
public abstract class PublicBaseClass
{
protected readonly InternalTypeA _fieldA;
...
}
And thus the problem, the protected member is visible outside the assembly but is of an internal type, so it won't compile.
The issue at hand is how to I (or can I?) tell the compiler that only public classes in the same assembly as PublicBaseClass may inherit from it and therefore _fieldA will not be expossed outside of the assembly?
Or is there another way to do what I want to do, have a public super class and a set of public base classes that are all in the same assembly and use internal types from that assembly in their common ("protected") code?
The only idea I have had so far is the following:
public abstract class PublicBaseClass
{
private readonly InternalTypeA _fieldA;
protected object FieldA { get { return _fieldA; } }
...
}
public class SubClass1 : PublicBaseClass
{
private InternalTypeA _fieldA { get { return (InternalTypeA)FieldA; } }
}
public class SubClass2 : PublicBaseClass
{
private InternalTypeA _fieldA { get { return (InternalTypeA)FieldA; } }
}
But that is UGLY!
The CLR provides a FamilyAndAssembly accessibility which will do what you want, but there isn't the syntax in C# to use it.
The workaround is to make the variable field internal, and you'll have to trust the code in your assembly to not access it inappropriately.
You can also make the constructor of PublicBaseClass internal, so only your assembly can instantiate it. That way, only your classes can inherit off it (even if the class itself is public)
The cleanest way to deal with this is the use of public interfaces and private classes. If your refactoring existing code this is not always an option. One easy way to ease the pain of that conversion is to use a public abstract class instead of an interface and expose a static factory method.
Example:
public abstract class MyClass
{
public static MyClass New()
{ return new InternalMyClass(); }
}
class InternalMyClass : MyClass
{ }