I have a broker class that issues request objects and expects them to be delivered back to it with a couple properties changed to sensible values. The problem is that the consumers of said broker must never change a couple readonly properties of that object nor be able to create a different request instance to cheat that readonly protection or the broker will break and throw an exception. I want to find a way to make the compilation fail if any class save for the broker tries to create a request object.
I think sealing the instantiation of the request objects so it can only be done from inside the broker itself is a neat idea coupled with readonly properties so request processors can never cheat the system but i am having a hard time doing so. I tried a child class with a private constructor like this:
public class PermissionsRequestBroker {
public PermissionsRequest Test() {
return new PermissionsRequest();
}
private class PermissionsRequest {
private PermissionsRequest() {
}
}
}
But it fails because the broker cannot create the request object.
I tried a similar approach but with an interface like this:
public class PermissionsRequestBroker {
public IPermissionsRequest Test() {
return new PermissionsRequest();
}
public interface IPermissionsRequest {
}
private class PermissionsRequest : IPermissionsRequest {
public PermissionsRequest() {
}
}
}
But the request processors can implement IPermissionsRequest and cheat the system that way. Sure i could implement a runtime check so the object returned is still the broker's PermissionRequest object but that's still a runtime check and will throw an exception.
I'm all for exceptions but i feel there must be some way to enforce that contract at compile time without installing any IDE extension or NuGet package of any kind.
Place PermissionsRequestBroker and PermissionsRequest in a separate assembly together, and mark PermissionsRequest as internal instead of public. Then if you need consumers to be able to hold onto an instance of the PermissionsRequest object, wrap it in another class that is public.
Something like the following:
public class PermissionsRequestBroker {
public PermissionsRequestWrapper Test() {
return new PermissionsRequestWrapper( new PermissionsRequest() );
}
}
internal class PermissionsRequest {
internal PermissionsRequest() {
}
}
// Use 'sealed' to prevent others from inheriting from this class
public sealed class PermissionsRequestWrapper {
private PermissionsRequest _permissionsRequest;
internal PermissionsRequestWrapper(PermissionsRequest permissionsRequest) {
_permissionsRequest = permissionsRequest;
}
/* etc... */
}
I know this is already answered, but I'm curious... why wouldn't this work?
EDIT: Had a brain freeze moment, the below code will not work, see the edit after that.
public class PermissionsRequestBroker {
public PermissionsRequest Test() {
return new PermissionsRequest();
}
public sealed class PermissionsRequest {
private PermissionsRequest() {
}
}
}
Basically making the inner class public and sealed but only its constructor private?
EDIT
If we invert this, it would be simpler to implement, thoughts? The staticness of the broker is optional of course.
public class PermissionsRequest
{
private PermissionsRequest()
{ }
public sealed class Broker
{
public static PermissionsRequest CreatePermissionsRequest()
{
return new PermissionsRequest();
}
public PermissionsRequest CreatePermissionsRequest_Instance()
{
return new PermissionsRequest();
}
}
}
public class UserClass
{
public void Blah()
{
var permissionsRequest = PermissionsRequest.Broker.CreatePermissionsRequest();
var broker = new PermissionsRequest.Broker();
var permRequest = broker.CreatePermissionsRequest_Instance();
}
}
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();
}
Hi i want to have a class that cannot be instantiated but can be added as a static field to another class but i could not achieve it;
Here is what i've done;
public class ValueListManager
{
public static Operations myOps { get { return new Ops(); } }
}
public interface Operations
{
void Call();
}
public class Ops : Operations
{
public void Call()
{
}
}
I dont' want the Ops class to be instantiated anywhere else. Basically I want to be able to;
ValueListManager.Operations.Call();
But i dont want to be able to use the ops class like;
var ops = new Ops();
Is there a way to achieve this?
You can achieve that by declaring the Ops class as a private class within the ValueListManager class where you want to use it:
public class ValueListManager
{
private class Ops : Operations
{
public Ops()
{
}
public void Call()
{
}
}
public static Operations myOps { get { return new Ops(); } }
}
Note, that in this example based on your code, a new instance of the Ops class is created every time you access the myOps property. If you don't want that, you need to store the Ops instance in a static field once it is created and use that in the Getter of the property.
As I understand you want to instantiate this class only once and later use it.
You can use Singletone pattern, you can also use inheritance with this pattern.
public class Ops: Operations
{
private static Ops instance;
private Ops() {}
public static Ops Instance
{
get
{
if (instance == null)
{
instance = new Ops();
}
return instance;
}
}
public void Call()
{
// do something
}
}
and where you want to use it you can call its method:
Ops.Instance.Call()
If you don't want to nest your classes for some reason, and don't want to basically change anything except the Ops class itself, you could put your code into a different assembly (add a class library to your solution), and make the constructor internal:
public class ValueListManager
{
public static Operations myOps { get { return new Ops(); } }
}
public class Ops : Operations
{
internal Ops() {}
public void Call()
{
}
}
Then you'd only need to add a reference to that assembly from the one you want to use that, you'd not need to change any other code.
The constructor (thus new Ops()) can only be accessed from that assembly, code in other assemblies won't be able to new.
This is very similar to the design pattern singleton, but it is unclear from your code if you want only one instance or if you don't want to instantiate it from elsewhere?
If it is a single instance you're after the most recommended way to implement a singleton in c# is using the static constructor:
public class Single
{
private static Single instance;
private Single() { }
static Single()
{
instance = new Single();
}
public static Single Instance
{
get { return instance; }
}
}
Most other ways have (at least a theoretical) risk of threading issues.
However it should be noted that the singleton pattern (and typically extensive use of static methods) is in some contexts an indication of a bad design.
I have a program that needs to be able to interface with multiple platforms ie read/write files, read/write database or read/write web requests. The platform interface is selected from configuration and does not change while the application is running. I have a single read/write interface class which is inherited by the platform specific classes so that this is abstracted from the rest of the program.
My problem is that I have 10 classes in my framework that will need to use this interface. Instead of making multiple instances of this class, or passing a single reference to every class, I figured it would make sense to make the interface static. Unfortunately I have just learned that Interfaces cannot have static methods, static methods cannot call non-static methods and static methods cannot be abstract.
Can anyone show me another method of approaching this situation?
Edit:
Thanks for everyone's input, here is my solution based on the example given by Patrick Hofman (thank you!)
interface TheInterface
{
void read();
void write();
}
public class X : TheInterface
{
public void read() { //do something }
public void write() { //do something }
}
public class Y : TheInterface
{
public void read() { //do something }
public void write() { //do something }
}
public class FileAccessor
{
public static TheInterface accessor;
public static TheInterface Accessor
{
get
{
if(accessor) return accessor;
}
}
}
This can be called by any class as:
static void Main(string[] args)
{
switch (Config.interface)
{
case "X":
FileAccessor.accessor = new Lazy<X>();
case "Y":
FileAccessor.accessor = new Lazy<Y>();
default:
throw new Lazy<Exception>("Unknown interface: " + Config.interface);
}
FileAccessor.Accessor.read();
}
Indeed, interfaces, or abstract classes can't be static themselves, but the further implementation can. Also, you can use the singleton pattern to make your life easier, and allow inheritance, etc.
public class X : ISomeInterface
{
private X() { }
public static X instance;
public static X Instance
{
get
{
return instance ?? (instance = new X());
}
}
}
Or, using Lazy<T>:
public class X : ISomeInterface
{
private X() { }
public static Lazy<X> instanceLazy = new Lazy<X>(() => new X());
public static X Instance
{
get
{
return instance.Value;
}
}
}
Disclaimer: I am the author of the library described below.
I don't know if this helps you, but I have written a library (very early version yet) that allows you to define static interfaces, by defining normal interfaces and decorating their methods with an attribute named [Static], for example:
public interface IYourInterface
{
[Static]
void DoTheThing();
}
(Note that you don't explicitly add this interface to your implementations.)
Once you have defined the interface, you can instantiate it from within your code with any valid implementation you choose:
return typeof(YourImplementation).ToStaticContract<IYourInterface>();
If the methods can't be found in YourImplementation, this call fails at runtime with an exception.
If the methods are found and this call is successful, then the client code can polymorphically call your static methods like this:
IYourInterface proxy = GetAnImplementation();
proxy.DoTheThing();
You can make a Static Class which has Variable of your Interface.
public static class StaticClass
{
public static ISomeInterface Interface;
}
Now you can access the Instance from everywhere in your Framwork
static void Main(string[] args)
{
StaticClass.Interface = new SomeClass();
}
I know there is a 'internal' keyword and [InternalsVisibleTo] attribute. But how to allow a class in class level that is not in the same assembly to modify private data in ? That is, only allow a particular class in an assembly to access private data but not evey classes under that assembly?
I asked this question before here How to implement C++ like friend relationship in C# but it is not specific enough, so I ask again here.
Other discussion related to the theory and reason why C# not use friend was discussed here
Why does C# not provide the C++ style 'friend' keyword?
I have thought about it and I think I have a solution by reflection. Not sure is it a good way to do it.
If I have SomeClass that has a friend FriendClass. NotFriendClass and FriendClass are in the same assembly but only FriendClass can access SomeClass's private data. Here is what SomeClass needs:
class SomeClass
{
private bool isMyFriend()
{
StackTrace st = new StackTrace();
StackFrame callerSF = st.GetFrame(2);
MethodBase mb = callerSF.GetMethod();
Type callerType = mb.DeclaringType;
// FriendClass is my friend
if (typeof(FriendClass) == callerType)
return true;
else
return false;
}
// ....
In this method SomeClass checks whether the caller class is his friend. Yes it has a hardcoded if (typeof(FriendClass) == callerType) but C++ friend also need to hardcode the class name in the declaration.
For those "friend-awared" methods of SomeClass, it should be like:
public bool SetData(int x)
{
if (!isMyFriend())
return false;
this.privateData = x;
return true;
}
The only problem is it is a run-time checking. But still, I think it is good enough for porting some program from C++ to C# using friend.
I usually translate cases where a friend keyword seems handy into a pattern where a class itself determines which classes can instantiate it, without breaking proper OO-design.
The idea is that the class that wants control over who can instantiate, offers friendship to the classes that are allowed to get an instance of it. For example, class InControl allows classes ChosenOne and ChosenTwo to obtain instances of InControl.
A 'chosen' class (i.e. ChosenOne or ChosenTwo) can 'engage' the friendship offered by InControl with an instance of itself (friendship.engage(this)) and the friendship in turn can 'accept' that instance by providing it an instance of InControl (friend.accept(new InControl())).
The actual friendship is implemented with a nested single instance Friendship class. Friendship is confined to 'chosen' classes using a generic IFriendship interface with T being a chosen class. In turn, each 'chosen' class needs to implement the generic IFriendable interface with T being InControl, to be able to receive an instance of InControl.
The InControl class has a private constructor to avoid instantiation by anyone else but friends:
public interface IFriendable<T>
{
void accept(T friend);
}
public interface IFriendship<T>
{
void engage(T friend);
}
public class ChosenOne : IFriendable<InControl>
{
private InControl _friend { get; set; }
private ChosenOne()
{
InControl.friendship.engage(this);
}
public void accept(InControl friend)
{
_friend = friend;
}
}
public class ChosenTwo : IFriendable<InControl>
{
private InControl _friend { get; set; }
private ChosenTwo()
{
InControl.friendship.engage(this);
}
public void accept(InControl friend)
{
_friend = friend;
}
}
public class InControl
{
public interface IFriendship : IFriendship<ChosenOne>, IFriendship<ChosenTwo> { }
public static IFriendship friendship { get { return Friendship.instance; } }
private class Friendship : IFriendship
{
static Friendship()
{
}
internal static readonly Friendship instance = new Friendship();
public void engage(ChosenOne friend)
{
friend.accept(new InControl());
}
public void engage(ChosenTwo friend)
{
friend.accept(new InControl());
}
}
private InControl()
{
}
}
I would like to ask what are the risks of having something as follows:
abstract public class HtmlTemplateBuilder
{
HtmlSource source;
protected HtmlTemplateBuilder()
{
LoadTemplates();
}
public abstract void LoadTemplates();
}
The risk is if a derived class derives from the derived class:
DerivedClass2 -> #DerivedClass1 -> HtmlTemplateBuilder
This can be solved by sealing #DerviedClass1, but are there any more risks or better practices for implementing this functionality?
Thanks
The situation in which this pattern bit me is as follows: at some later stage you want to add a specialized HtmlTemplateBuilder, which can load different templates based on some criteria unknown to the class itself (maybe you decide you want some cool templates on a specific day of the year). That is:
public class SpecialHtmlTemplateBuilder : HtmlTemplateBuilder
{
private bool someCondition;
public override void LoadTemplates()
{
if (someCondition)
{
LoadTemplatesSet1();
}
else
{
LoadTemplatesSet2();
}
}
}
But how are you going to pass someCondition to the class? The following won't work:
public class SpecialHtmlTemplateBuilder : HtmlTemplateBuilder
{
private bool someCondition;
public SpecialHtmlTemplateBuilder (bool someCondition)
{
this.someCondition = someCondition;
}
// ...
}
because the assignment of this.someCondition will be done after calling the base constructor, i.e., after LoadTemplates() is called. Note that sealing derived classes does not solve this problem.
The way to solve this is as #Rahul Misra described: add an explicit Initialize method and call that after the constructor.
Have a look at this link which explains the perils with simple easy to understand examples
https://blogs.msmvps.com/peterritchie/2012/04/25/virtual-method-call-from-constructor-what-could-go-wrong/
I would remove the call to LoadTemplates from constructor and call Initialise on it when the templates actually need to be loaded and used.
abstract public class HtmlTemplateBuilder
{
HtmlSource source;
object locker = new object();
private bool initialised;
protected HtmlTemplateBuilder()
{
}
protected void Initialise()
{
lock (locker)
{
if(initialised)
{
LoadTemplates();
initialised = true;
}
}
}
public abstract void LoadTemplates();
}