Here is my code (just a snippet to expose the problem) :
public class A
{
class B
{
//private class
}
public int nb;
}
Im tired but why can't I access to "nb" in my private class ?
You're gonna need an instance of A in order to access the instance member nb:
public class A
{
class B
{
public B()
{
A a = new A();
int nb = a.nb;
}
}
public int nb;
}
It's possible in java but not in C#.
You need to pass an instance of A to B.
In C# an 'outer' class is just a 'namespace' to the inner class. So the outer class is not being instantiated.
You need to pass an instance of A to B, like so:
public class A
{
class B
{
private A _outerClass;
public B(A outerClass)
{
_outerClass = outerClass;
// Then you can access nb thus:
_outerClass.nb;
}
}
public int nb;
}
Related
I have two classes, class A and class B.
public class A
{
public int someNumber;
public A(int a)
{
someNumber = a;
}
}
Now class B has a field that is an object of class A. In C++ it is possible to do this:
public class B
{
public A foo;
public B(int a) : foo(a) { }
}
But this doesnt work in C#. So how can one solve this problem in C# without using a default constructor in class A. To be more precise, how is it possible to write a constructor for class B that takes as parameter the someNumber value of foo?
You could try something like this:
public class B
{
public A thing;
public B(int a)
{
thing = new A(a);
}
}
I just came up with a really odd problem and I wasn't able to figure out how to solve it.
I have 3 classes, the class A is the base for B and C, that is:
class A { ... }
class B : A { ... }
class C : B { ... }
Now I would like to have a static property in these classes that stores the last object of each classes created, for example:
class A
{
static public A lastInstance;
}
class B : A
{
public B()
{
lastInstance = this;
}
}
class C : A
{
public C()
{
lastInstance = this;
}
}
What I would like to achieve is to be able to retrieve an instance for each subclass, for example:
var v1 = new B();
var v2 = new C();
var v3 = B.lastInstance; // v3 == v1 and v3 != v2
var v4 = C.lastInstance; // v4 == v2 and v4 != v3
Is it possible anyhow?
The only approach that seems promising to me shown in C# Static instance members for each inherited class: is it really the only chance I have to avoid defining a static member manually for each class?
I think this could be done with Dictionary and that's the only way i can think of right now:
class A {
static Dictionary<Type, A> _LastInstances = new Dictionary<Type, A>(); // because every subclass will inherit from A
public static A LastInstance {
get {
if ( _LastInstances.ContainsKey(GetType()) ) {
return _LastInstances[GetType()];
}
return null;
}
protected set {
if ( _LastInstances.ContainsKey(GetType()) ) {
_LastInstances[GetType()] = value;
} else {
_LastInstances.Add(GetType(), value);
}
}
}
class B : A {
public B(){
LastInstance = this;
}
}
At first: yes you can. But you missed two points with your implementation.
As you declared the lastInstance as public in class A every derived class can use it. As you declared it as static every instance of A will copy itself into it. But so will every instance of B, C and every other class with id derived from A: they all use the same instance. Thus the last instatiated class is saved and everything instantiated before is overwritten.
To overcome this, you must have a static property LastInstance (I switched to my naming convention) on every class, which you can accomplish by using the new modifier on derived classes
public class A
{
public static A LastInstance { get; private set; }
...
}
public class B : A
{
public static new B LastInstance { get; private set; }
...
}
But you're not done with that alone, because
When you create a new instance of B the (default-)construstor first makes a call into the construtor of A. Thus a reference to any already created instance of a base class is overwritten by the currently created instance of the derived class. So your constructors should look like this:
public class A
{
public static A LastInstance { get; private set; }
public A()
{
if (this.GetType() == typeof(A))
{
LastInstance = this;
}
}
}
public class B : A
{
public static new B LastInstance { get; private set; }
public B()
{
if (this.GetType() == typeof(B))
{
LastInstance = this;
}
}
}
This way you will get the correct lastly created instance (if any) in each classes static LastInstance.
Hope this helps
Because static members aren't inherited, you won't be able to access B.lastInstance if class A defines lastInstance. The suggestion you linked to seems reasonable. Although I don't have enough information on why you're attempting this, you could consider using a factory class that holds onto the latest created object.
Here's an example. This is not a good long term solution if you plan to have many classes deriving from A.
class HoldLastKnownFactory
{
B CreateB() { ... }
C CreateC() { ... }
B LastB { get {...} }
C LastC { get {...} }
}
Is there a way, and not using reflection, of elegant get only child propeties of an object?
For example:
class A
{
public string PropA;
}
class B : A
{
public string PropB;
}
class C
{
var classB_instance = new B();
/* Only class B properties without parent so B.PropB; but no B.PropA;
}
I know it would be possible with reflection, but if this can be avoided?
You could create a specific interface for your inherited class like say
interface ISpecificB {
string PropB;
}
and then Create your class like
public class A {
public string PropA;
}
public class B: A, ISpecificB {
public string PropB;
}
and only make the variable as specific as ISpecificB when creating it or returning it from a function
ISpecificB classB = new B();
classB.PropA // shouldn't be available
However, classB could still be casted as B or A which would give access to the propA and it might increase complexity in your solution
Whether you can do this way ?
class A
{
private string PropA;
}
class B : A
{
public string PropB;
}
class C
{
var classB_instance = new B();
}
You could mark PropA as private, look at https://msdn.microsoft.com/en-us/library/ms173121.aspx:
private
The type or member can be accessed only by code in the same class or struct.
just a short note: most of the time, I use reflection to do exactly the opposite: access things I am not allowed, for example, because they are private... ;-) reflection is not a "tool" to hide something, AFAIK. it opens every door which is usually locked ;-)
You can use the protected accessibility modifier:
The type or member can be accessed only by code in the same class or struct, or in a class that is derived from that class.
public class A
{
protected string PropA { get; set; }
}
public class B : A
{
public string PropB { get; set; }
}
public class C
{
var classB_instance = new B();
//You can't access classB_instance.PropA
}
Declare variable PropA of Class A as private variable(as show in below code):
class A
{
private string PropA;
}
I have an outer class with an inner class like this :
class A
{
public class B
{
public int number;
}
}
I think inner class is useful because I can call my "number" field like this :
A.B.number = X; but I can't call it this shape !
I create an instance from A, for example => A a = new A();
I want to access B by a instance directly => a.B.number;
but I can't.
I know if I create a new from B; I can access it, But I want to know how I can call my field in this shape => A.B.number NOT b.number
in brief, how I can access B class by call A class. (not directly B)
Instead of putting the B class description in A you can just put a property in A that is of type B.
public class B
{
public int number;
}
public class A
{
public A()
{
MyB = new B();
}
public B MyB { get; private set; }
}
Then you can do the following
A myA = new A();
int num = myA.MyB.number;
Though I would suggest also making number in B a property as well.
An inner class is just a class, and if you want to refer to its properties you need to have an object of that.
I think,you should make an object of B.
class A
{
public B b = new B();
public class B
{
public int number;
}
}
I wrote this answer to take experts opinion on it.
class A
{
public B b{ get; private set; }
public A()
{
b= new B();
}
public class B
{
public int number;
}
}
A a = new A();
Now you can access
a.b.number;
Class A will not automatically instantiate an instance of class B. You would need to create a property that returned an instance of B.
For example
public class A {
public A() {
this.MyB = new B()
}
public B MyB {get; set;}
}
You could then delegate to B if you wanted to get a property of b directly.
public int BNumber
{
get
{
return MyB.number;
}
}
With that said, why do you want a nested class here? Class B doesn't need to be nested in A for A to have a property of type B. I think you may be conflating class definition with property definition.
I have error
Cannot access a non-static member of outer type 'Project.Neuro' via
nested type 'Project.Neuro.Net'
with code like this (simplified):
class Neuro
{
public class Net
{
public void SomeMethod()
{
int x = OtherMethod(); // error is here
}
}
public int OtherMethod() // its outside Neuro.Net class
{
return 123;
}
}
I can move problematic method to Neuro.Net class, but I need this method outside.
Im kind of objective programming newbie.
Thanks in advance.
The problem is that nested classes are not derived classes, so the methods in the outer class are not inherited.
Some options are
Make the method static:
class Neuro
{
public class Net
{
public void SomeMethod()
{
int x = Neuro.OtherMethod();
}
}
public static int OtherMethod()
{
return 123;
}
}
Use inheritance instead of nesting classes:
public class Neuro // Neuro has to be public in order to have a public class inherit from it.
{
public static int OtherMethod()
{
return 123;
}
}
public class Net : Neuro
{
public void SomeMethod()
{
int x = OtherMethod();
}
}
Create an instance of Neuro:
class Neuro
{
public class Net
{
public void SomeMethod()
{
Neuro n = new Neuro();
int x = n.OtherMethod();
}
}
public int OtherMethod()
{
return 123;
}
}
you need to instantiate an object of type Neuro somewhere in your code and call OtherMethod on it, since OtherMethod is not a static method. Whether you create this object inside of SomeMethod, or pass it as an argument to it is up to you. Something like:
// somewhere in the code
var neuroObject = new Neuro();
// inside SomeMethod()
int x = neuroObject.OtherMethod();
alternatively, you can make OtherMethod static, which will allow you to call it from SomeMethod as you currently are.
Even though class is nested within another class, it is still not obvious which instance of outer class talks to which instance of inner class. I could create an instance of inner class and pass it to the another instance of outer class.
Therefore, you need specific instance to call this OtherMethod().
You can pass the instance on creation:
class Neuro
{
public class Net
{
private Neuro _parent;
public Net(Neuro parent)
{
_parent = parent;
}
public void SomeMethod()
{
_parent.OtherMethod();
}
}
public int OtherMethod()
{
return 123;
}
}
I think making an instance of outer class in inner class is not a good option because you may executing business logic on outer class constructor. Making static methods or properties is better option. If you insist making an instance of outer class than you should add another parameter to outer class contructor that not to execute business logic.