Nested class with hidden constructor impossible in c#? - c#

I' ve been doing some programming lately and faced an issue which i found weird in c#. (at least for me)
public class Foo
{
//whatever
public class FooSpecificCollection : IList<Bar>
{
//implementation details
}
public FooSpecificCollection GetFoosStuff()
{
//return the collection
}
}
I want the consumer of Foo to be able to obtain a reference to FooSpecificCollection, even perform some operations on it. Maybe even set it to some other property of Foo or smth like that, but not To be able to CREATE an instance of this class. (the only class that should be able to instatiate this collection should be Foo.
Is my request really that far-fetched? I know that people way smarter defined c# but shouldn't there be such an option that a parent class can create a nested class instance but nobody else can't.
So far I created a solution to make an abstract class, or interface available through the property and implement a concrete private class that is not available anywhere else.
Is this a correct way to handle such a situation.?

The way embedded classes work is that they, as members of the outer class, get access to private members of that outer class. But not the other way around (what is what you want).
You can shield the constructor of FooSpecificCollection, but then the Factory has to be part of FooSpecificCollection itself. It could enlist the outer class:
public class Foo
{
public class FooSpecificCollection : List<Bar>
{
private FooSpecificCollection () { }
public static FooSpecificCollection GetFoosStuff()
{
var collection = new FooSpecificCollection ();
PrepareFooSpecificCollection(collection);
return collection;
}
}
private static void PrepareFooSpecificCollection(FooSpecificCollection collection)
{
//prepare the collection
}
}

Make your nested class private and make the return value of GetFoosStuff IList<Bar> instead of FooSpecificCollection.
Also, there's a good chance that deriving from List<Bar> is a bug.

If you are creating a library for others to use, you could make the constructor internal. Anyone outside the library will not be able to access it. If you are concerned about calling the constructor in your own project, just don't call it outside the parent class.
We create classes all the time which are not directly related to other classes, but the constructors don't have to be hidden from non-related classes. We (the programmers) know the the objects are not related so we don't ever create an instance of one in the other.

There is a solution but I don't think I would use it in my App :)
The idea is to have derived class from FooSpecific which is private and can be used only inside Foo but has public constructor, so Foo can create its instances.
public class Foo
{
//whatever
public class FooSpecific
{
// Protected contructor.
protected FooSpecific()
{
}
// All other code in here.
}
// Private helper class used for initialization.
private class FooSpecificInitHelper : FooSpecific
{
public FooSpecificInitHelper()
{
}
}
// Method in foo to create instaces of FooSpecific.
private FooSpecific CreateFooSpecific()
{
return new FooSpecificInitHelper();
}
}

No, and it doesn't really make sense.
I mean the whole point is so that you could potentially return other instances; but who will be deriving from that class anyway? Certainly not any other classes (Because that would be wrong, and imply it shouldn't be hidden inside the main class), so ...

Related

Is there a way to automatically get a reference to the object calling the constructor?

Right now in my code, I have an abstract class, which contains a nested class. In the constructor of every class implementing my abstract class, I will have to construct an instance of the nested class, and pass a reference to the current object to the nested class, as demonstrated below.
public abstract class MainClass
{
public SpecializedClass SpecialStuff { get; init; }
/* General stuff happens here*/
public class SpecializedClass
{
private MainClass _parent;
public SpecializedClass(MainClass parent, object stuff)
{
this._parent = parent;
// Do stuff...
}
/* More specialized stuff happens here.*/
}
}
public class Foo : MainClass
{
public Foo()
{
this.SpecialStuff = new SpecializedClass(this, "stuff"); // <= This is the issue
// More stuff
}
}
As you can see, whenever I need to call new SpecializedClass(), I have to pass a reference to this. Is there a way to do this automatically, so the classes inheriting from MainClass don't need to keep passing references down?
There answer is basically no. The stack frame does not contain a reference to the calling object (if any), there is no way to get at it fundamentally unless you pass it in, or want to walk the stack (bad idea).
There are however situations where you can use expression trees for more complicated less trivial problems. however, they hardly apply here, and would be more printable characters anyway.
I guess another approach would be an extension methods, however you are just kicking the this ball up the road and creating more code for no good reason
Which leaves with a instance method or base class...
Lastly, although common, I would double check you actually need the calling object. This can easily brush up on design issues such as the Single Responsibility principle (SRP) and Separation of concerns (SOC) among others
All things being equal, if you need it then just pass it in.
No, this is not possible.
Think about it: You could run SpecialStuff = new SpecializedClass(this, "stuff"); in a static function. Then what would the value of this be?
It seems that you could push that functionality into the base abstract class.
Now you only need to call the SpecializedClass and pass this once
public abstract class MainClass
{
public SpecializedClass SpecialStuff { get; init; }
public MainClass(object stuff)
{
this.SpecialStuff = new SpecializedClass(this, stuff);
}
/* General stuff happens here*/
public class SpecializedClass
{
private MainClass _parent;
public SpecializedClass(MainClass parent, object stuff)
{
this._parent = parent;
// Do stuff...
}
/* More specialized stuff happens here.*/
}
}
public class Foo : MainClass
{
public Foo() : base("stuff")
{
// More stuff
}
}

C#: Giving access to private members without 3-fold code duplication

I have a class
public class Foo{
public Foo{...}
private void someFunction(){...}
...
private Acessor{
new Acessor
}
}
with some private functionality (someFunction). However, sometimes, I want to allow another class to call Foo.SomeFunction, so I have an inner class access Foo and pass out that:
public class Foo{
public Foo{...}
private void someFunction(){...}
...
public Acessor{
Foo _myFoo;
new Acessor(Foo foo){_myFoo = foo;}
public void someFunction(){
_myFoo.someFunction();
}
}
}
With this code, if I want a Foo to give someone else pemission to call someFunction, Foo can pass out a new Foo.Accessor(this).
Unfortunately, this code allows anyone to create a Foo.Accessor initiated with a Foo, and they can access someFunction! We don't want that. However, if we make Foo.Accessor private, then we can't pass it out of Foo.
My solution right now is to make Acessor a private class and let it implement a public interface IFooAccessor; then, I pass out the Foo.Accessor as an IFooAccessor. This works, but it means that I have to declaration every method that Foo.Accessor uses an extra time in IFooAccessor. Therefore, if I want to refactor the signature of this method (for example, by having someFunction take a parameter), I would need to introduce changes in three places. I've had to do this several times, and it is starting to really bother me. Is there a better way?
If someFunction has to be accessible for classes in the same assembly, use internal instead of private modifier.
http://msdn.microsoft.com/en-us/library/7c5ka91b(v=vs.71).aspx
If it has to be accessible for classes which are not in the same assemble then, it should be public. But, if it will be used by just a few classes in other assemblies, you probably should think better how you are organizing you code.
It's difficult to answer this question, since it's not clear (to me at least) what exactly you want to achieve. (You write make it difficult for someone to inadverdantly use this code in a comment).
Maybe, if the method is to be used in a special context only, then explicitly implementing an interface might be what you want:
public interface ISomeContract {
void someFunction();
}
public class Foo : ISomeContract {
public Foo() {...}
void ISomeContract.someFunction() {...}
}
This would mean, that a client of that class would have to cast it to ISomeContract to call someFunction():
var foo = new Foo();
var x = foo as ISomeContract;
x.someFunction();
I had a similar problem. A class that was simple, elegant and easy to understand, except for one ugly method that had to be called in one layer, that was not supposed to be called further down the food chain. Especially not by the consumers of this class.
What I ended up doing was to create an extension on my base class in a separate namespace that the normal callers of my classes would not be using. As my method needed private access this was combined with explicit interface implementation shown by M4N.
namespace MyProject.Whatever
{
internal interface IHidden
{
void Manipulate();
}
internal class MyClass : IHidden
{
private string privateMember = "World!";
public void SayHello()
{
Console.WriteLine("Hello " + privateMember);
}
void IHidden.Manipulate()
{
privateMember = "Universe!";
}
}
}
namespace MyProject.Whatever.Manipulatable
{
static class MyClassExtension
{
public static void Manipulate(this MyClass instance)
{
((IHidden)instance).Manipulate();
}
}
}

Private class with Public method?

Here is a piece of code:
private class myClass
{
public static void Main()
{
}
}
'or'
private class myClass
{
public void method()
{
}
}
I know, first one will not work. And second one will.
But why first is not working? Is there any specific reason for it?
Actually looking for a solution in this perspective, thats why made it bold. Sorry
It would be meaningful in this scenario; you have a public class SomeClass, inside which you want to encapsulate some functionality that is only relevant to SomeClass. You could do this by declaring a private class (SomePrivateClass in my example) within SomeClass, as shown below.
public class SomeClass
{
private class SomePrivateClass
{
public void DoSomething()
{
}
}
// Only SomeClass has access to SomePrivateClass,
// and can access its public methods, properties etc
}
This holds true regardless of whether SomePrivateClass is static, or contains public static methods.
I would call this a nested class, and it is explored in another StackOverflow thread.
Richard Ev gave a use case of access inside a nested classes. Another use case for nested classes is private implementation of a public interface:
public class MySpecialCollection<T> : IEnumerable<T>
{
public IEnumerator<T> GetEnumerator()
{
return new MySpecialEnumerator(...);
}
private class MySpecialEnumerator : IEnumerator<T>
{
public bool MoveNext() { ... }
public T Current
{
get { return ...; }
}
// etc...
}
}
This allows one to provide a private (or protected or internal) implementation of a public interface or base class. The consumer need not know nor care about the concrete implementation. This can also be done without nested classes by having the MySpecialEnumerator class be internal, as you cannot have non-nested private classes.
The BCL uses non-public implementations extensively. For example, objects returned by LINQ operators are non-public classes that implement IEnumerable<T>.
This code is syntactically correct. But the big question is: is it useful, or at least usable in the context where you want to use it? Probably not, since the Main method must be in a public class.
Main() method is where application execution begin, so the reason you cannot compile your first class (with public static void Main()) is because you already have Main method somewhere else in your application. The compiler don't know where to begin execute your application.
Your application must have only one Main method to compile with default behavior otherwise you need to add /main option when you compile it.

Visibility of nested class constructor

Is there a way to limit the instantiation of the nested class in C#? I want to prevent nested class being instantiated from any other class except the nesting class, but to allow full access to the nested class from other code.
Usually I create an interface for the functionality you want to expose to other classes, then make the nested class private and implement that interface. This way the nested class definition can stay hidden:
public class Outer
{
private class Nested : IFace
{
public Nested(...)
{
}
//interface member implementations...
}
public IFace GetNested()
{
return new Nested();
}
}
If you need to meet one of the following requirements:
You want the nested class to be sealed,
You don't want to copy all the nested class's method signatures to an interface like in Lee's answer,
I found a solution similar to the one posted by ak99372, but without using a static initializer:
public class Outer
{
private interface IPrivateFactory<T>
{
T CreateInstance();
}
public sealed class Nested
{
private Nested() {
// private constructor, accessible only to the class Factory.
}
public class Factory : IPrivateFactory<Nested>
{
Nested IPrivateFactory<Nested>.CreateInstance() { return new Nested(); }
}
}
public Nested GetNested() {
// We couldn't write these lines outside of the `Outer` class.
IPrivateFactory<Nested> factory = new Nested.Factory();
return factory.CreateInstance();
}
}
The idea is that the Nested class's constructor is accessible only to the Factory class, which is nested one level deeper. The Factory class explicitly implements the method CreateInstance from the private interface IPrivateFactory, so that only those who can see IPrivateFactory can call CreateInstance and get a new instance of Nested.
Code outside the Outer class can't freely create instances of Nested without asking Outer.GetNested(), because
Outer.Nested's constructor is privated, so they can't call it directly
Outer.Nested.Factory can be instantiated, but can't be cast to IPrivateFactory, so its CreateInstance() method can't be called.
Note that I wouldn't recommend using that pattern heavily in production code, but it's a trick I find useful to have up my sleeve on rare occasions.
In short, no, you cannot do that. There is an accessibity modifier "public" which means "accessible by anything inside me or outside me" and there is an accessibility modifier "private" which means "accessible by anything inside me". There is no modifier which means "accessible to the thing immediately outside me but not to anything outside it", which is what you would need to mark the constructor as. That's simply not a concept that the designers of the type system thought would be useful.
Can you describe why you want this crazy kind of accessibility? Perhaps there is a better way to get what you want.
Since there is nothing in C# syntax you'll have to implement something like "a contract" between them. You can take advantage of the fact that nested class can access private fields of its parent:
public class ParentClass
{
private static Func<FriendClass> _friendContract;
public class FriendClass
{
static FriendClass()
{
_friendContract= () => new FriendClass();
}
private FriendClass() { }
}
///Usage
public FriendClass MethodUse()
{
var fInstance = _friendContract();
//fInstance.DoSomething();
return fInstance;
}
}
Of course you can adjust the contract to handle different parameters
private static Func<Arg1,Arg2,FriendClass> _friendContract;
For the answer proposed by Joshua Smith I found it necessary to force the static constructor of FriendClass to run, achieved by calling an empty static Initalize() method on FriendClass from the static constructor of ParentClass.
With the new static abstract interface members of C# 11 you can limit the instantiation of nested classes quite neatly:
public class Outer
{
protected interface INestedFactory<T> where T : INestedFactory<T>
{
public static abstract T CreateInstance();
}
public class SomeNested : INestedFactory<SomeNested>
{
private SomeNested() { }
static SomeNested INestedFactory<SomeNested>.CreateInstance()
{
return new SomeNested();
}
}
protected void CreateNested<T>() where T : INestedFactory<T>
{
T.CreateInstance();
}
}
public class Outer
{
public class Nested
{
readonly Outer Outer;
public Nested(Outer outer /* , parameters */)
{
Outer = outer;
// implementation
}
// implementation
}
public Nested GetNested(/* parameters */) => new Nested(this /* , parameters */);
}
Note that you can access private members of Outer from Nested.

How to create a constructor that is only usable by a specific class. (C++ Friend equivalent in c#)

As far as I know, in C#, there is no support for the "friend" key word as in C++. Is there an alternative way to design a class that could achieve this same end result without resorting to the un-available "friend" key-word?
For those who don't already know, the Friend key word allows the programmer to specify that a member of class "X" can be accessed and used only by class "Y". But to any other class the member appears private so they cannot be accessed. Class "Y" does not have to inherit from class "X".
No, there is no way to do that in C#.
One common workaround is to based the object for which you want to hide the constructor on an interface. You can then use the other object to construct a private, nested class implementing that interface, and return it via a Factory. This prevents the outside world from constructing your object directly, since they only ever see and interact with the interface.
public interface IMyObject
{
void DoSomething();
}
public class MyFriendClass
{
IMyObject GetObject() { return new MyObject(); }
class MyObject : IMyObject
{
public void DoSomething() { // ... Do something here
}
}
}
This is how I solved it. I'm not sure if it's the "right" way to do it, but it required minimal effort:
public abstract class X
{
// "friend" member
protected X()
{
}
// a bunch of stuff that I didn't feel like shadowing in an interface
}
public class Y
{
private X _x;
public Y()
{
_x = new ConstructibleX();
}
public X GetX()
{
return _x;
}
private class ConstructibleX : X
{
public ConstructibleX()
: base()
{}
}
}
No. The closest you have is an internal constructor, or a private constructor and a separate factory method (probably internal, so you haven't saved much).
What about just having it explicity implement an interface that is only visible to a certain class?
Something like:
public void IFreindOfX.Foo() //This is a method in the class that's a 'friend' to class X.
{
/* Do Stuff */
}
and then make sure IFriendOfX is visible to class X. In your X class you'd call the method by first casting X to IFriendOfX then calling Foo(). Another advantage is that is is fairly self documenting... that is, it's pretty close to having the friend keyword itself.
What about creating a private class? This does exactly what you seem to be describing. A member of class X can be accessed and used only by class Y, and to any other class it appears private, since, well, it is private:
public class Y
{
private class X { }
private X Friend;
public Y()
{
Friend = new X();
}
}
As far as I know, the Internal keyword is the closest thing in .NET. This question will shed more light on Internal: Internal in C#
The only thing I can think of that would even come close would be protected internal but that does not restrict it to a specific class. The only friending I'm aware of in c# is to make a friend assembly. Still does not restrict to a specific class.
The only thing I could think of to try and do it would be to do something like the following:
public class A
{
public A() {}
protected internal A(B b) {}
}
public class B
{
A myVersion;
public B()
{
myVersion = A(this);
}
}
The only other way I could think of would be to do some sort of Constructor Injection using reflection that is done inside of your friend class. The injection mechanism would allow you to limit it to what you want but could be very cumbersome. Take a look at something like Spring.Net for some injection capabilities.
As a workaround, I suppose you could create a conditional in your constructor that uses reflection.
For example, if Class1's constructor must be called by Class2:
public Class1()
{
string callingClass = new StackFrame(1).GetMethod().DeclaringType.Name;
if (callingClass != "Class2")
{
throw new ApplicationException(
string.Concat("Class1 constructor can not be called by ",
callingClass, "."));
}
}
EDIT:
Please note that I would never actually do this in "real" code. Technically it works, but it's pretty nasty. I just thought it was creative. :)
You can access private members/methods using Reflection.
Since it's got the design tag, I never particularly liked the friend keyword. It pierces encapsulation and that always felt dirty to me.
This has a bit of a smell. There are other plenty of other ways to achieve implementation hiding in C#. Limiting construction to only specific classes does not achieve all that much.
Could you please provide more information as to the purpose of this requirement? As already answered, internal is the closest match for limiting accessibility to the class. There are ways to build on top of that depending on the purpose.

Categories

Resources