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
Related
Is it possible to access the method that has been overridden using the object of the derived class?
using System;
class Bclass
{
public virtual int result(int a,int b)
{
return a + b;
}
}
class Dclass:Bclass
{
public override int result(int a, int b)
{
return a - b;
}
}
public class Program
{
static public void Main(string[] args)
{
Dclass obj1 = new Dclass();
Console.WriteLine(obj1.result(10, 5));
}
}
Is there a way to get the output as 15?
From MSDN documentation:
The override modifier is required to extend or modify the abstract or
virtual implementation of an inherited method, property, indexer, or
event.
override modifier are designed to extend functionality of virtual function. When ever you call overridden function with the help of derived class object it will call overridden function.
To answer your question,
Is it possible to access the method that has been overridden using the
object of the derived class?
There is no way to call virtual method directly using derived class object
Ways to call virtual method:
Approach 1:
Create a new function in derived class and call base.result() from it.
public int BaseResult(int a, int b)
{
return base.result(a, b);
}
and call BaseResult() using derived class instance
Dclass obj1 = new Dclass();
Console.WriteLine(obj1.BaseResult(10, 5));
Try it online
Approach 2:
Create instance of base class and from that access virtual method.
Bclass obj2 = new Bclass();
Console.WriteLine(obj2.result(10, 5));
Unless you need to declare the base method as virtual for some reason, you could also achieve what you want by declaring the derived class method as new, thereby hiding the implementation when using it through an instance of the derived class.
At the same time, you can still access the base implementation by casting the object to the base class.
Following the example you provided:
class Bclass
{
public int result(int a,int b)
{
return a + b;
}
}
class Dclass : Bclass
{
public new int result(int a, int b)
{
return a - b;
}
public int BaseResult(int a, int b)
{
return base.result(a, b);
}
}
public class Program
{
public static void Main(string[] args)
{
Dclass obj1 = new Dclass();
Console.WriteLine(((Bclass)obj1).result(10, 5)); // 15
}
}
More information about the differences between override and new can be found in this MSDN article.
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
}
}
There are two clarifications I need which I am trying to understand.
I see that, I can access the variable "i" using "base" keyword as well as using the object. Is there any difference of it? I think, creation of object is memory consuming and hence we use base keyword itself to call base class members in derived class?
When to use this.i and base .i and object.i?
class Program
{
public Program()
{
i = 20;
}
public readonly int i = 10;
}
class C : Program
{
public C() : base()
{
//base.i = 20;
}
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//prints 20
Console.WriteLine(c.i);//prints 20
Console.WriteLine(this.i); //Also prints 20 :D
}
static void Main()
{
C c = new C();
c.Display();
Console.ReadLine();
}
I tried to accept one answer as that helped me understand few things. But still, my question "the difference ans usage of 3 different styles at my context and in other contexts" is not clear. So please care to share your thoughts on this, I would appreciate it. I am sure there are millions like me who try to understand this :)
As for 1) You can use both to access the property as the sub class has extended it. There will only be a difference if you override that in the sub class or if you decide to create a field with the same name in your sub class.
EDIT:
To override it, you can make it a virtual property in the base class
public class Base
{
public virtual int i {get; set;}
}
public class Sub : Base
{
public override int i { get; set; }
}
Problem 2 : Your StackOverflow
you care creating a new instance of Program every time you create a new instance of Program it seems to be an infinite loop.
class Program
{
Program p = new Program(); // <-- this line here
In your case there is no difference. Difference comes when you have field with same name in base class and derived class(typically we don't have it).
class Program
{
public int i = 10;
}
class C : Program
{
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//prints 10
Console.WriteLine(c.i);//prints 20
}
}
base keyword refers to base class, so base.i refers to "member named i" in base class.
Also worth noting that when you access a member with base keyword and it doesn't exist compiler will produce an error.
class Program
{
//public int i = 10; //No field named i
}
class C : Program
{
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//Compile time error here
Console.WriteLine(c.i);//this refers to C.i field
}
}
Answer for Question 1
Base you can use when you want to refer you prent class from the child class.
Example :
public class A
{
public int i {get;set;}
}
public class B:A
{
publi void readvalueofi()
{ Console.Writeln(base.i); }
}
This also useful when you override method of parent and want to call parent method from child
Example :
public class Parent
{
public virtual void Print()
{
Console.WriteLine("Print in Parent");
}
}
public class Child : Parent
{
public override void Print()
{
base.Print();
Console.WriteLine("Print in Child");
}
}
Answer for Question 2 :
Reason for StackOverflow Exception
You're creating an private instance of Program when Program is created so this is sort of an endless loop:
your first create Program instance. When this instance is creating it creates a new instance of Program. This instance also creates an instance of Programand again, and again etc.
So basially it creates infinite loop over here.
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.
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.