Inheriting class and call hidden base constructor - c#

Consider in AssemblyOne
public class A
{
internal A (string s)
{ }
}
public class B : A
{
internal B (string s) : base(s)
{ }
}
In AssemblyTwo
public class C : B
{
// Can't do this - ctor in B is inaccessible
public C (string s) : base(s)
}
Obviously this is a code smell, but regardless of if being a bad idea is it possible to call the ctor of B from the ctor of C without changing AssemblyOne?

Ignore Assembly Two for the moment. You would not be able to instantiate an instance of class C, because it inherits from B, which there are no public constructors for.
So if you remove the inheritance issue from Class C, you'd still have an issue creating instances of class B outside of B's assembly due to protection levels. You could use reflection to create instances of B, though.
For the purposes of testing, I altered your classes as follows:
public class A
{
internal A(string s)
{
PropSetByConstructor = s;
}
public string PropSetByConstructor { get; set; }
}
public class B : A
{
internal B(string s)
: base(s)
{
PropSetByConstructor = "Set by B:" + s;
}
}
I then wrote a console app to test:
static void Main(string[] args)
{
System.Reflection.ConstructorInfo ci = typeof(B).GetConstructors(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)[0];
B B_Object = (B)ci.Invoke(new object[]{"is reflection evil?"});
Console.WriteLine(B_Object.PropSetByConstructor);
Console.ReadLine();
}
I would not recommend doing this, its just bad practice. I suppose in all things there are exceptions, and the exception here is possibly having to deal with a 3rd party library that you can't extend. This would give you a way to instantiate and debug, if not inherit.

This is not possible, even with reflection.
If a class has no accessible constructors, there is no way to create a class that inherits it.

No, you must change AssemblyOne.

Related

is this possible in c# ? only one class access base class method and second class can not access the same base class method

A is base class
B is derived from A and also C is derived from A
I want only B can access the method of A , C an not access of that same method of A.
class A {
protected void Foo() {
}
}
class B : A {
void Bar() {
this.Foo(); // OK
}
}
class C : A {
void Baz() {
this.Foo(); // I don't want to permit this
}
}
HOW IT POSSIBLE IN c#
I think this look like a problem for Interface segregation principle:
Clients should not be forced to depend upon interfaces that they don't
use.
But in your case this can be rephrased for the class inheritance.
Create pure base class (without a method you want to hide from class C)
public class Base
{
protected void SomeDummyMethod()
{
}
}
Then create your A class which inherit from Base and add a method you what to share for class B
public class A : Base
{
protected void YourFooMethod()
{
}
}
Create B class which inherit from A and will have access to all functionality including YourFooMethod
public class B : A
{
public void Bar()
{
this.YourFooMethod();
}
}
And finally your C class which have all base functionality except YourFooMethod method
public class C : Base
{
public void Bar()
{
this.YourFooMethod(); //Compile error: YourFooMethod is not a member of...
}
}
I suppose you could write code in class A that checks the calling class name against a white list or a black list and throws an exception in the cases you want to disallow, but I would not recommend doing this. That would be very difficult to maintain, and class A should not need to know about every class that extends it.
What you are trying to do is really honestly a bad idea.
C# (and .NET in general) has the access modifiers:
public - Anyone can access
private - Only the containing scope/type can access
protected - Only the containing type and its derived types can access
internal - Only types defined in the same Assembly (or InternalsVisibleTo Assemblies) can access
protected internal - The set-union of protected and internal can access.
You're asking for something in-between private and protected, where you can manually restrict access to named types.
This is not currently possible to enforce, at least at compile-time, in .NET - though if types A and B exist in the same assembly and C exists in a different assembly then internal would work.
At runtime you could enforce this with code-access-security, or more simply: using reflection to get the calling-class's name (this.GetType()), or use a password:
or more simpler: a password requirement:
class A {
private Boolean isAllowedAccess;
protected A(String password) {
this.isAllowedAccess = password == "12345abc";
}
protected void Foo() {
if( !this.isAllowedAccess ) throw new InvalidOperationException();
}
}
class B : A {
public B() : base("12345abc") {
}
void Bar() {
this.Foo(); // OK
}
}
class C : A {
public C() : base(null) {
}
void Baz() {
this.Foo(); // I don't want to permit this
}
}

C# equivalent to C++ friend keyword?

I am new to C#, and I have a problem for which in C++ I would normally use the friend identifier. Now I know the friend keyword doesn't exist in C#, but I don't have any experience with how to work around this (except for making all class variables public properties, which I want to avoid if I can).
I have the following scenario:
public class A
{
public string Info { get; set; }
/* much more data */
}
public class B
{
private A m_instanceOfA;
public B(A a) { m_instanceOfA = a; }
public Info { get return A.info; set A.Info = value; }
/* And some more data of its own*/
}
public class C
{
private A m_instanceOfA;
// I need a constructor of C, which needs to set C.m_instanceOfA
// to the same value as b.m_instanceOfA.
public C(B b) { m_instanceOfA = b.m_instanceOfA ; } // <--- Not allowed!
/* And some more data of its own*/
}
Is there any other clever way, without making B.m_instanceOfA public, to give C access to this variable (only in the constructor)?
You can use the trick shown below to create a method FriendRecieveMessageFromAlice on Bob that can only be called by Alice. An evil class, Eve, won't be able to call that method without using reflection on private members.
I'm curious to know if this or another solution have been suggested before by other people. I've been looking for a solution to that problem for months, and I never saw one that ensured real friend semantics provided that reflection isn't used (you can circumvent nearly anything with it).
Alice and Bob
public interface IKey { }
public class Alice
{
// Alice, Bob and Carol must only have private constructors, so only nested classes can subclass them.
private Alice() { }
public static Alice Create() { return new Alice(); }
private class AlicePrivateKey : Alice, IKey { }
public void PublicSendMessageToBob() {
Bob.Create().FriendRecieveMessageFromAlice<AlicePrivateKey>(42);
}
public void FriendRecieveMessageFromBob<TKey>(int message) where TKey : Bob, IKey {
System.Console.WriteLine("Alice: I recieved message {0} from my friend Bob.", message);
}
}
public class Bob
{
private Bob() { }
public static Bob Create() { return new Bob(); }
private class BobPrivateKey : Bob, IKey { }
public void PublicSendMessageToAlice() {
Alice.Create().FriendRecieveMessageFromBob<BobPrivateKey>(1337);
}
public void FriendRecieveMessageFromAlice<TKey>(int message) where TKey : Alice, IKey {
System.Console.WriteLine("Bob: I recieved message {0} from my friend Alice.", message);
}
}
class Program
{
static void Main(string[] args) {
Alice.Create().PublicSendMessageToBob();
Bob.Create().PublicSendMessageToAlice();
}
}
Eve
public class Eve
{
// Eve can't write that, it won't compile:
// 'Alice.Alice()' is inaccessible due to its protection level
private class EvePrivateKey : Alice, IKey { }
public void PublicSendMesssageToBob() {
// Eve can't write that either:
// 'Alice.AlicePrivateKey' is inaccessible due to its protection level
Bob.Create().FriendRecieveMessageFromAlice<Alice.AlicePrivateKey>(42);
}
}
How it works
The trick is that the method Bob.FriendRecieveMessageFromAlice requires a (dummy) generic type parameter which serves as a token. That generic type must inherit from both Alice, and from a dummy interface IKey.
Since Alice does not implement IKey itself, the caller needs to provide some subclass of Alice which does implement IKey. However, Alice only has private constructors, so it can only be subclassed by nested classes, and not by classes declared elsewhere.
This means that only a class nested in Alice can subclass it to implement IKey. That's what AlicePrivateKey does, and since it is declared private, only Alice can pass it as the generic argument to the Bob.FriendRecieveMessageFromAlice, so only Alice can call that method.
We then do the same thing the other way round so that only Bob can call Alice.FriendRecieveMessageFromBob.
Leaking the key
It is worth noting that, when called, Bob.FriendRecieveMessageFromAlice has access to the TKey generic type parameter, and could use it to spoof a call from Alice on another method OtherClass.OtherMethod<OtherTkey> accepting a OtherTKey : Alice, IKey. It would therefore be safer to make the keys inherit from distinct interfaces: Alice, IBobKey for the first, and Alice, IOtherKey for the second.
Better than C++ friend
Even Bob itself can't call its own method Bob.FriendRecieveMessageFromAlice.
Bob can have multiple friends with distinct friend methods:
// Can only be called by Alice, not by Carol or Bob itself
Bob.FriendRecieveMessageFromAlice <TKey>(int message) where TKey : Alice, IKey { }
// Can only be called by Carol, not by Alice or Bob itself
Bob.FriendRecieveMessageFromCarol <TKey>(int message) where TKey : Carol, IKey { }
I'd be interested to know if there is some way to find tricks like this in a more efficient way than brute-force trial and error. Some kind of "algebra of C#'s type system", that tells us what restrictions can be enforced and what can't, but I haven't seen any discussion on that kind of topic.
Internal
You can use the internal keyword. Your type (or type member) will then only be visible to other types within the same assembly; And also:
If you need your internal types to be visible from other assemblies, you can use the InternalsVisibleToAttribute. This attribute targets your whole assembly and is usually written in the AssemblyInfo.cs file.
PS: Friend keyword doesn't exists in C# but the concept of friendship exists (not exactly the same as the one in C++), it is described on the Friend Assemblies article from the MSDN. Note also that a friend keyword exists in VB.NET and has the exact same behaviour than the C# internal keyword.
You can only use 5 accessibility modifiers:
public Access is not restricted.
protected Access is limited to the containing class or types derived from the containing class.
internal Access is limited to the current assembly.
protected internal
Access is limited to the current assembly or types derived from the containing class.
private
Access is limited to the containing type.
I modified the code you posted, so it should work as you want exactly:
using System.Reflection;
using System.Diagnostics;
public class A
{
public string Info { get; set; }
/* much more data */
}
public class B
{
private A m_instanceOfA;
public string Info { get; set; }
public B(A a) => Info = a;
private readonly ConstructorInfo friend = typeof(C).GetConstructor(new Type[] { typeof(B) });
public A InstanceOfA
{
get
{
if (new StackFrame(1).GetMethod() != friend)
throw new Exception("Call this property only inside the constructor of C");
return this.m_instanceOfA;
}
}
}
public class C
{
private A m_instanceOfA;
// Only the constructor of C can set his m_instanceOfA
// to the same value as b.m_instanceOfA.
public C(B b)
{
Info = b.InstanceOfA; // Call the public property, not the private field. Now it is allowed and it will work too, because you call it inside the constructor of C. In Main method, for example, an exception will be thrown, if you try to get InstanceOfA there.
}
}
I think you're looking for the "internal" keyword - basically only visible to classes in the same assembly
Alternatively you could so something like (excuse the method names!) :
public interface IAmAFriendOfB {
void DoSomethingWithA(A instanceOfA);
}
public class B {
private A m_instanceOfA;
public B(A a) { m_instanceOfA = a; }
public void BeFriendlyWith(IAmAFriendOfB friend) {
friend.DoSomethingWithA(m_instanceOfA);
}
// the rest of your class
}
public class C : IAmAFriendOfB {
private A m_instanceOfA;
public C(B b) {
b.BeFriendlyWith(this);
}
void DoSomethingWithA(A instanceOfA) {
m_instanceOfA = b.m_instanceOfA;
}
}
Here's another alternative using an internal class with a private singleton instance, which allows you to fine-tune which methods are exposed to the pseudo-friend class.
using System;
namespace Test
{
public class A
{
public string Info { get; set; }
/* much more data */
}
public class B
{
private A m_instanceOfA;
public B(A a) { m_instanceOfA = a; }
public string Info
{
get { return m_instanceOfA.Info; }
set { m_instanceOfA.Info = value; }
}
// requires an instance of a private object, this establishes our pseudo-friendship
internal A GetInstanceOfA(C.AGetter getter) { return getter.Get(m_instanceOfA); }
/* And some more data of its own*/
}
public class C
{
private A m_instanceOfA;
private static AGetter m_AGetter; // initialized before first use; not visible outside of C
// class needs to be visible to B, actual instance does not (we call b.GetInstanceOfA from C)
internal class AGetter
{
static AGetter() { m_AGetter = new AGetter(); } // initialize singleton
private AGetter() { } // disallow instantiation except our private singleton in C
public A Get(A a) { return a; } // force a NullReferenceException if calling b.GetInstanceOfA(null)
}
static C()
{
// ensure that m_AGetter is initialized
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(AGetter).TypeHandle);
}
public C(B b)
{
m_instanceOfA = b.GetInstanceOfA(m_AGetter);
}
public string Info
{
get { return m_instanceOfA.Info; }
set { m_instanceOfA.Info = value; }
}
/* And some more data of its own*/
}
public class Test
{
public static void Main()
{
A a = new A();
B b = new B(a);
C c = new C(b);
c.Info = "Hello World!";
Console.WriteLine(a.Info);
}
}
}
Live Demo
The C.AGetter class cannot be instantiated outside of itself, so C.m_AGetter (which is both private and static) represents a singleton instance that is only accessible from within C. As B.GetInstanceOfA requires an instance of C.AGetter, this makes the function useless outside of C. The function is marked internal to minimize its exposure, but the argument should also act as a form of self-documentation that it isn't meant for common use.
The interface alternative risks exposing methods beyond their intended scope (e.g., a class implementing the interface where it should not have access to the exposed methods), while this approach prevents that. Naysayers of friend access may still object to it, but this keeps things much closer to the intended scope.

How to force single inheritance?

I have two classes:
public class A
{
}
public sealed class B : A
{
}
And I want that only my B class (defined in the same assembly of A) can inherits A.
How can I do?
And I want that only my B class (defined in the same assembly of A) can inherits A. How can I do?
There is simply no need for inheritance then..
public sealed class B
{
//includes all methods of A and B
}
You can use a internal constructor, this prevents other assemblies from using your class.
public class A
{
internal A() { }
}
public sealed class B : A { }
And, if you don't care about performance:
public class A
{
public A()
{
Type c = GetType();
if (c != typeof(A) && c != typeof(B)) throw ....;
}
}
I suggest you use composition instead of inheritance to restrict the visibility of base type members.
If only B can inherit A, then do you really need inheritance in the first place?
If it's to split a class that became too big, you're not following good practice as it is not likely to have a single responsibility.
Now if for some awkward reason you actually do need this, you can try that:
public class B
{
private sealed class A : B
{
}
}
And tweak it to your needs.

Class constructor error

Since we know that constructor is not inherited in the child class as i asked in the my previous question Click here to view question
I had write the code
namespace TestConscoleApplication
{
abstract public class A
{
public int c;
public int d;
private A(int a, int b)
{
c = a;
d = b;
}
public virtual void Display1()
{
Console.WriteLine("{0}{1}", c, d);
}
}
internal class B : A
{
protected string Msg;
public B(string Err)
{
Msg = Err;
}
public void Display()
{
Console.WriteLine(Msg);
}
}
class Program
{
static void Main(string[] args)
{
B ObjB = new B("Hello");
Console.ReadLine();
}
}
}
when i compile the code its showing an error
Error TestConscoleApplication.A.A(int, int) is inaccessible due to its protection level.
Then why it is showing an error.
By making the only constructor of A private, you've prevented derived classes from being able to be constructed outside A.
Derived class constructor always call the base constructor (one of). Making it private you prohibit access to it from outside. In other words you make it impossible to make an instance of A outside A.
Since you made a constructor, the compiler won't generate a default public one for this class for you.
If you want to provide access to it from the class descendant but not from outside, you should make it protected.
You need to have a constructor for A accessible to B, and use it. Also, the default base constructor is base() (i.e. the parameterless constructor), which doesn't exist on A. Here's one way you can resolve this (nonessential bits removed):
abstract public class A
{
protected A(int a, int b)
{
}
}
internal class B : A
{
public B(int a, int b, string Err)
: base(a, b)
{
}
}
constructors shouldn't be private otherwise you will not be able to create an instance of that class and won't be able to inherit it too, but if you want to create a private constructor create a public one with it too.
For more info Go here

How to hide static method

Let's say I have a classes, like that:
class A
{
public static int Count()
}
class B : A
{
}
class C : A
{
}
How can I hide this static method for class B but not for C?
You can't, basically. Heck, if it's public then anyone can call it.
You could make it protected which would allow it to be called from within B or C but not elsewhere... but you still couldn't differentiate between B and C.
You could do it by creating another class, let's call it Special, that inherits A. Then you would make C inherit from Special and B inherit from A. Also, you would have the static method protected, that means only classes that inherited Special will have access to it.
class A
{
}
class Special : A
{
protected static int Count()
}
class B : A
{
}
class C : Special
{
}
The only solution would be to change your class hierarchy. It's not worth the hassle and WTF moments you will get in code reviews it if you ask me.
class ABase
{
}
class A
{
public static int Count()
}
class B : ABase
{
}
class C : ABase
{
}

Categories