How to restrict class members to only one other class - c#

I want to access class members that are in Class1 from another class (Class2) but I want to access it just from that class and to forbid access form any other class, form, etc. Is there any way to do this?

The only way to do this is to nest the classes, and then make the data private:
public class Class1
{
private object data;
public class Class2
{
public void Foo(Class1 parent)
{
Console.WriteLine(parent.data);
}
}
}

You can use nested class with private scope:
public class Class2
{
public Class2()
{
Class1 c1 = new Class1();
Console.WriteLine(c1.Id);
}
private class Class1
{
public int Id { get; set; }
}
}

Actually, you can do this with a bit of lateral thinking. One way is to create a method on Class1 that accepts an instance of Class2 and returns delegates to access the members which are marked private. Then declare Class2 as sealed to prevent someone sneaking in with inheritance.
Another way would be to inspect the call stack with a StackFrame in each member (fields are out for this) and throw an Exception if the caller isn't the desired type.
Lord knows.why you'd do this though! :)

You want a c# equivalent of "friend", but there isn't really one. This previous question gives possible solutions.

You can make an interface, that expose properties for access to your private members. And implement it explicitly. Than use that interface in other class.
2-nd way is to use reflection.
3-rd is nested classes.

you may implement a property
[IsAllowed(true)]
public class a
{
}
then at your,method you may change the sign of each method requiring the instance.
public class b {
public void method ( object aClassInstace){
.... Here check the property
}
}

Related

Preventing Inheritance?

How can i prevent a class from from being inherited
without using Sealed Keyword?
Thanks in advance.
In your class's constructor:
public MyUnsealedClass()
{
if (this.GetType() != typeof(MyUnsealedClass))
throw new Exception("Don't do that");
}
Why not use the sealed keyword though?
Another way is you can make a static method that returns an object of your type and then make the constructor private. This has the advantage that it will create a compile time error instead of a run time error.
You can use private constructors
class Base
{
private Base() {}
}
class Derived : Base
{
// derp
}
Then provide a utility to creaet Base objects (like static methods on Base that have access to the private ctor
class Base
{
private Base() {}
public static Base CreateBase() { return new Base(); }
}
Also, if you want to be able to derive from this class, but you don't want other people doing that, you can make your class internal (or even the ctor internal)
class Base
{
internal Base() { }
}
class Derived : Base
{
}
// in another assembly
class MyOwnDerived : Base
{
// derp
}
You can achieve this by using private constructor, something along the lines:
public class NonInheritableClass
{
static NonInheritableClass GetObject()
{
return new NonInheritableClass();
}
private NonInheritableClass()
{
}
}
Throwing an exception in the constructor will work.
I agree though - why not use sealed? It's there for that reason.
Unless you' are trying to do something else, and if that's the case, there is probably a better solution too.

C# Inheritance to hide inherited Members

I read other threads like this but they didn't work for me.
I got two classes:
public class ClassA
{
public string _shouldBeInteger;
public string _shouldBeBool;
public string _shouldBeDateTime;
}
public class ClassB : ClassA
{
public int? shouldBeInteger
{
get { return (_shouldBeInteger != null) ? Convert.ToInt32(Convert.ToDouble(_shouldBeInteger)) : new int?(); }
set { _shouldBeInteger = Convert.ToString(value); }
}
//... same thing with datetime etc.
}
If I now create a new object of ClassB I get
_shouldBeInteger, _shouldBeBool, _shouldBeDateTime;
shouldBeInteger,shouldBeBool,shouldBeDateTime
But I want to hide the _variables to the User.
Setting them private in ClassB will override them, but I need to access them in order to parse there string values.
Update
There is a ClassC filling ClassAs' values, which mainly is the reason why they have to be writeable. There is no way for me to change the way that works, but I'm fully in Control of ClassA and ClassB
ClassC //not changeAble for me
{
//infomagic filling values of ClassA
}
Setting ClassA variables to private won't work, because programmer of ClassA produced it in a strange way.
Solution
Because ClassA needs to be writeable, but not readable to other classes than inheritated, I finally got this:
ClassA
{
public string _shouldBeInteger { protected get; set; }
//and so on
}
which causes ClassB to work with theese properties, without giving them outside.
Intellisense still shows them, but you might consider using:
[EditorBrowsable(EditorBrowsableState.Never)]
to solve that.
Thanks to all.
I think you can solve your problem using:
public class ClassA
{
protected string _shouldBeInteger;
protected string _shouldBeBool;
protected string _shouldBeDateTime;
}
so those variables are accessible to derived classes but not to user.
EDITED after user update:
I don't know if this could be a vali solution for you, but try:
public class ClassB : ClassA
{
public new int? _shouldBeInteger
{
get { return (base._shouldBeInteger != null) ?
Convert.ToInt32(Convert.ToDouble(base._shouldBeInteger)) :
new int?(); }
set { base._shouldBeInteger = Convert.ToString(value); }
}
}
Inheritance can't hide the members as you would think. The new modifier exists to "hide" a base member, but that doesn't play nice when talking to base types.
http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
You can either change the access level of the fields (the preferred way) or you can wrap the class instead of inheriting from it and provide simple pass-through methods to delegate to the wrapped class. This is called the Adapter Pattern:
public class ClassB
{
private ClassA _wrappedClass;
}
Just as an aside, your public fields are following the naming convention commonly used for private fields.
The required access level for derived classes is protected. If the members are used publicly but in the same assembly you can use protected internal. If the members are used publicly by other assemblies... I'd suggest refactoring.
The problem is that you declared the fields public in the base class. In order not to violate the polymorphic nature of inheritance, anything public in the base class must be public in all derived classes as well. If you could change that, you could never be sure that a ClassB could be passed to something expecting a ClassA.
Therefore, as other people have suggested, you probably want the base class fields to be declared protected, which is like private except derived classes can see them.
However if you do need to access them via an actual instance of ClassA, you could declare them private and give them virtual public properties which the derived class can then override. This at least allows the derived class to change their behaviour, but it still can't actually hide them.
If that also doesn't fit, then it's probably worth considering using composition instead of inheritance because the substitution principle is actually getting in your way, and that's an inheritance fundamental.
If you don't have control over ClassA, you'll need to create a wrapper/adapter class like so:
public class ClassB
{
private readonly _classA = new ClassA();
public int? shouldBeInteger
{
get
{
return (this._classA._shouldBeInteger != null)
? Convert.ToInt32(Convert.ToDouble(this._classA._shouldBeInteger))
: new int?();
}
set
{
this._classA._shouldBeInteger = Convert.ToString(value);
}
}
}
public class ClassB
{
private int shouldBeInteger;
public int ShouldBeInteger
{
get { return shouldBeInteger; }
set { shouldBeInteger = value; }
}
}
OR
public class ClassB
{
public int ShouldBeInteger{ get; set; }
}
In both of this case ShouldBeInteger will be accesible outside the class.
In first case there were a private field, which cannot be accesible outside the class,
values to private filed can be set through the public field.
In second case the compiler automatically create a private backing field and do the same
process as above. This is auto implemented property.
Hope this may help you.

How do I create a method or property in C# that is public, yet not inheritable?

Here is an example. I have two classes, one inherited, and both have a function with the same name, but different arguments:
public class MyClass
{
//public class members
public MyClass()
{
//constructor code
}
public void Copy(MyClass classToCopy)
{
//copy code
}
}
public class InheritedClass : MyClass
{
//public class members
public InheritedClass():base()
{
//constructor code
}
public void Copy(InheritedClass inheritedClassToCopy)
{
//copy code
}
}
My question is how do I make the base class' copy method (MyClass.Copy) non-inheritable or non-visible in InheritedClass? I don't want to be able to do this:
MyClass a;
InheritedClass b;
b.Copy(a);
Does this make sense, or should I keep this functionality in there? Can what I'm asking even be done?
Does this make sense, or should I keep this functionality in there? Can what I'm asking even be done?
Trying to hide a public method like this when used by a base class is problematic. You're purposely trying to violate the Liskov substitution principle.
You can't do what you are wanting to do here; C# does not allow negative variance in inherited members. (almost no languages truly do, actually)
It may be that you don't want an inherited class here at all, though; what you may really want is an interface. Or... your two classes here may not have the correct relationship; perhaps they should both instead be common siblings of a third class, which is their parent.
You can use explicit interface implementation to hide this method from the inheritor. But you will need to add an interface of course and you will need to cast your type to the interface to call your method:
public interface MyInterface
{
void Copy(MyClass classToCopy)
}
public class MyClass : MyInterface
{
void MyInterface.Copy(MyClass classToCopy)
{
//copy code
}
}
This is not possible. An inherited class inherits all public and protected members, methods and properties. Using the sealed modifier with make it non-overridable, but still accessible to your inherited class.
What everyone else said, but if I am inferring your goal correctly, it is to make sure that InheritedClass users never use the MyClass method. In that case, exclude it from MyClass and make two classes that inherit it.
Make MyBaseClass abstract if it should not be instantiated (most likely).
(Edited -- you probably would want to include copy code for anything that's part of the base class in the base class)
public abstract class MyBaseClass
{
public MyClass()
{
//constructor code
}
protected void Copy(MyBaseClass classToCopy)
{
//copy code
}
// other methods that all inherited classes can use
}
public class MyClass: MyBaseClass
{
public MyClass():base()
{
//constructor code
}
public void Copy(MyClass myClassToCopy)
{
base.Copy(myClassToCopy);
//specific copy code for this extensions in this class
}
}
public class InheritedClass : MyBaseClass
{
public InheritedClass():base()
{
//constructor code
}
public void Copy(InheritedClass inheritedClassToCopy)
{
base.Copy(myClassToCopy);
//specific copy code for this extensions in this class
}
}

C# do nested classes need to be instantiated?

In the following scenario:
public class outerclass
{
public innerClass Ic
{get;set}
public class innerClass
{
}
}
Do you need to instantiate the inner class property before assigning values to it, like this?
public class outerclass
{
public outerclass()
{
this.Ic = new innerClass();
}
public innerClass Ic
{get;set}
public class innerClass
{
}
}
It doesn't matter in what scope class has been declared - you should always work with classes in the same manner: before interacting with a particular class instance you have to create it using new operator.
Yes, unlike a base class you need to instantiate an inner class if you wish to use it.
You can prove this to yourself quite easily by trying it:
public class OuterClass
{
public InnerClass Ic { get; set; }
public class InnerClass
{
public InnerClass()
{
Foo = 42;
}
public int Foo { get; set; }
}
}
public class Program
{
static void Main()
{
Console.WriteLine(new OuterClass().Ic.Foo);
}
}
The above code throws a NullReferenceException because Ic has not been assigned.
I would also advise you to follow the Microsoft naming convention and use pascal case for type names.
In this case the answer doesn't depend on the fact that the class is defined inside your outer class. Because you used the automatic getter/setter, a hidden backing field is used for the property Ic. Like all fields of reference type, this field has a default value of null. Thus if you try to access the members of Ic without setting it to refer to some instance, you can expect a NullReferenceException.
Everything I just said would still be true even if innerClass was defined somewhere else.
No, the property is an instance of the class. The set would set a new instance anyway. No need to construct one unless you want to make sure the get never returns null.

How can I prevent a base constructor from being called by an inheritor in C#?

I've got a (poorly written) base class that I want to wrap in a proxy object. The base class resembles the following:
public class BaseClass : SomeOtherBase
{
public BaseClass() {}
public BaseClass(int someValue) {}
//...more code, not important here
}
and, my proxy resembles:
public BaseClassProxy : BaseClass
{
public BaseClassProxy(bool fakeOut){}
}
Without the "fakeOut" constructor, the base constructor is expected to be called. However, with it, I expected it to not be called. Either way, I either need a way to not call any base class constructors, or some other way to effectively proxy this (evil) class.
There is a way to create an object without calling any instance constructors.
Before you proceed, be very sure you want to do it this way. 99% of the time this is the wrong solution.
This is how you do it:
FormatterServices.GetUninitializedObject(typeof(MyClass));
Call it in place of the object's constructor. It will create and return you an instance without calling any constructors or field initializers.
When you deserialize an object in WCF, it uses this method to create the object. When this happens, constructors and even field initializers are not run.
If you do not explicitly call any constructor in the base class, the parameterless constructor will be called implicitly. There's no way around it, you cannot instantiate a class without a constructor being called.
At least 1 ctor has to be called. The only way around it I see is containment. Have the class inside or referencing the other class.
I don't believe you can get around calling the constructor. But you could do something like this:
public class BaseClass : SomeOtherBase
{
public BaseClass() {}
protected virtual void Setup()
{
}
}
public BaseClassProxy : BaseClass
{
bool _fakeOut;
protected BaseClassProxy(bool fakeOut)
{
_fakeOut = fakeOut;
Setup();
}
public override void Setup()
{
if(_fakeOut)
{
base.Setup();
}
//Your other constructor code
}
}
If what you want is to not call either of the two base class constructors, this cannot be done.
C# class constructors must call base class constructors. If you don't call one explicitly, base( ) is implied. In your example, if you do not specify which base class constructor to call, it is the same as:
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base() { }
}
If you prefer to use the other base class constructor, you can use:
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base(someIntValue) { }
}
Either way, one of the two will be called, explicitly or implicitly.
When you create a BaseClassProxy object it NEEDS to create a instance of it's base class, so you need to call the base class constructor, what you can doo is choose wich one to call, like:
public BaseClassProxy (bool fakeOut) : base (10) {}
To call the second constructor instead of the first one
I am affraid that not base calling constructor isn't option.
I ended up doing something like this:
public class BaseClassProxy : BaseClass
{
public BaseClass BaseClass { get; private set; }
public virtual int MethodINeedToOverride(){}
public virtual string PropertyINeedToOverride() { get; protected set; }
}
This got me around some of the bad practices of the base class.
constructors are public by nature. do not use a constructor and use another for construction and make it private.so you would create an instance with no paramtersand call that function for constructing your object instance.
All right, here is an ugly solution to the problem of one class inheriting the constructors of another class that I didn't want to allow some of them to work. I was hoping to avoid using this in my class but here it is:
Here is my class constructor:
public MyClass();
{
throw new Exception("Error: Must call constructor with parameters.");
}
OK now you were warned that it was ugly. No complaints please!
I wanted to force at least the minimal parameters from my main constructor without it allowing the inherited base constructor with no parameters.
I also believe that if you create a constructor and do not put the : base() after it that it will not call the base class constructor. And if you create constructors for all of the ones in the base class and provide the same exact parameters for them in the main class, that it will not pass through. But this can be tedious if you have a lot of constructors in the base class!
It is possible to create an object without calling the parameterless constructor (see answer above). But I use code like this to create a base class and an inherited class, in which I can choose whether to execute the base class's init.
public class MyClass_Base
{
public MyClass_Base()
{
/// Don't call the InitClass() when the object is inherited
/// !!! CAUTION: The inherited constructor must call InitClass() itself when init is needed !!!
if (this.GetType().IsSubclassOf(typeof(MyClass_Base)) == false)
{
this.InitClass();
}
}
protected void InitClass()
{
// The init stuff
}
}
public class MyClass : MyClass_Base
{
public MyClass(bool callBaseClassInit)
{
if(callBaseClassInit == true)
base.InitClass();
}
}
Here is my solution to the problem
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(new Child().Test);
}
public class Child : Parent {
public Child() : base(false) {
//No Parent Constructor called
}
}
public class Parent {
public int Test {get;set;}
public Parent()
{
Test = 5;
}
public Parent(bool NoBase){
//Don't do anything
}
}
}
A simple elegant solution. You can change it according to your need.
Another simple solution from me:
class parent
{
public parent()
{
//code for all children
if (this.GetType() == typeof(child1))
{
//code only for objects of class "child1"
}
else
{
//code for objects of other child classes
}
}
}
class child1 : parent
{
public child1()
{}
}
// class child2: parent ... child3 : parent ... e.t.c

Categories

Resources