Suppose that I've this situation:
Base class or Mother class that declare this structure:
public static class Mother
{
private static Childs _child = new Childs();
public static Childs Child
{
get { return _child; }
}
}
How you can see I want implement a singleton base class for access to all methods in one place as: Mother.Child.SomeMethod.
With this structure I've a better code organization.
Now I want make the Childs class only as internal, so here start the problem 'cause I can't create a public property of an internal class. The structure of internal class is the following:
internal class Childs
{
public static bool SomeMethod() { ... }
}
so how can I make a public property of an internal class?
If the child is internal, the static access point should be internal as well.
If you actually want to have public access to some members of the child, consider using an interface.
Anyway, if there is a static access point, you don't need to make members static.
public static class Mother
{
private static Child _child = new Child();
public static IChild Child
{
get { return _child; }
}
}
public interface IChild
{
// public stuff here
bool SomeMethod();
}
internal class Child : IChild
{
public bool SomeMethod() { ... }
// additional internal members here
}
All classes in the inheritance tree must have at least the same visibility as the highest class in the hierarchy. There is no way to have a public class derive from an internal class.
Maybe your Childs class public. If you want to, you can make it abstract to prevent instantiating it or make the constructor internal to prevent deriving it in another assembly.
You cannot do that. If the property is public, any other class can access it. But if they are able to get it, they must also be able to access the class being received.
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();
}
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.
Hello i have the following problem:
I have a struct
public struct Cell
{
public Node Value;
public static implicit Cell(Node value)=>new Cell(value); //can't since node less accesible then cell
}
This struct Cell contains a property of type Node which is an abstract base class and currently is internal with all its derived classes.What i need is to somehow make the Cell struct accesible for other developers so that they can extract the value of the Node without knowing the Node derived class.
internal abstract class Node{
internal class ANode:Node{
public byte[] internalValue;
}
internal class BNode:Node{
public int internalValue;
}
}
How can i achieve this? The cell is exposed to outside and so should the abstract base class Node.The user should be able to implicit cast from Node to Cell.
Current approach
What i have tried so far is define an interface IRaw for Node that extracts the content from the Node derived classes.The explicit implementation is a virtual method ,overloaded in the derived classes.
interface IRaw{
byte[] GetRaw();
}
internal abstract class Node:IRaw
{
byte[] IRaw.GetRaw()=>this.GetRaw();
protected virtual byte[] GetRaw(){ ....}
}
internal class ANode:Node
{
protected override byte[] GetRaw()
{
.....
}
}
The problem in the above approach is that i can not pass the IRaw as argument in the Cell constructor with the error code:
user defined conversions to or from an interface are not allowed.
public struct Cell
{
public IRaw Value;
public static implicit Cell(IRaw value)=>new Cell(value);
}
Any suggestions ?I practically need a "Bridge" between the Cell which is public and the contents of Node which are internal.
You can simply make Node public and keep its derived classes internal. Unrelated to that, you should think about not deriving Node in nested classes for better maintainability:
public abstract class Node {
}
internal class ANode : Node {
public byte[] internalValue;
}
internal class BNode : Node {
public int internalValue;
}
If you want to be able to create instances of ANode and BNode from external assemblies, you can use an abstract factory:
public static class NodeFactory {
public Node CreateNode(byte[] value) {
return new ANode { internalValue = value };
}
public Node CreateNode(int value) {
return new BNode { internalValue = value };
}
}
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
{ }