Access member variables from the MainClass inside a class defined in MainClass? - c#

I want to access the member variables inside a class MainClass, from inside a class defined in that MainClass. Can i do that?
public class MainClass
{
public int x = 1;
public class Class1
{
public void class1Function()
{
this.x = 4; //somehow access the x of instance of MainClass
}
}
public static class Class2
{
public static void class2Function()
{
this.x = 5; //also can i do this from a static function?
}
}
public void mainFunction()
{
System.Console.WriteLine(this.x); //this works just fine, obviously
}
}

Class1 and Class2 cannot access x from MainClass because an instance of a nested class isn't associated with an instance of the outer class. (Corrected based on Joe Sewell's hint)
You could inherit MainClass like this: public class Class1 : MainClass. Then you can access this.x.
Accessing a mutable variable from a static context, which is the case for Class2 is not possible. If you want to use x in class2Function you could pass it and return the modified version that you need (Closure of Operations).

Related

How to process data including protected members using extension method in C#

Recently, I had a need to process the private data contained in the base class using the methods of the child class. My base class could only contain domain-specific types (it only represents data). So first I decided to create a child-class in another project and implement the processing logic in it. But the problem is that once you create an instance of the base class, you can't cast it to the child type:
public class A
{
protected int member1;
public A(int value)
{
member1 = value;
}
}
public class B : A
{
public B (int value) : base(value)
{ }
public void DoSomething()
{
Console.Write(member1 * member1);
}
}
class Program
{
static void Main(string[] args)
{
A obj1 = new A(5);
B obj2 = (B)obj1; // InvalidCastException
obj2.DoSomething();
}
}
And I started thinking towards extension methods. However, you can't just access the protected fields of the class from them. In the end, I tried to combine the two approaches.
Here's my solution:
Make sure that you are allowed to add new methods to your base class and that your class is not sealed.
Add protected static method which returns the protected member you need.
Create an Extension class for your base class.
In extension class create a private nested class.
Inherit your nested class from your base class.
Create static method in nested class and implement the processing logic in (you can call static protected method from base class to get protected member from base class).
Create extension method in extension class and call static method of nested class in it.
The sample code is shown below:
public class A
{
protected int member1 = 0;
public A() {}
public A(int value)
{
member1 = value;
}
protected static int GetProtectedMember(A objA)
{
return objA.member1;
}
}
public static class AExtensions
{
public static void DoSomething(this A objA)
{
B.DoSomething(objA);
}
private class B : A
{
public static void DoSomething(A objA)
{
// objA.member1 // it's not allowed
int protectedFromA = A.GetProtectedMember(objA);
int sqr = protectedFromA * protectedFromA;
Console.WriteLine(sqr);
}
}
}
class Program
{
static void Main(string[] args)
{
A obj1 = new A(5);
obj1.DoSomething(); // 25
}
}
This way you can keep the classes that represent the data in a separate project and have multiple implementations of processing this data in different projects.

initialize constructor with new inside class in C#

I'm new to C# programming. I want to know why this is not possible:
// In file1.cs
public class Test {
public int Rt() {
return 10;
}
}
// In file2.cs
public class Test2 {
// initialize constructor here, but return compile-error
Test k = new Test();
static void Main() {
Console.Write(k.Rt()); // error here
}
}
Additional: I am learning C# for unity, so I also want to know if above is not possible then why this is not an error in unity
public class PlayerScript: MonoBehaviour {
public Vector2 speed = new Vector2(25, 25); // Not an error
void Update() {
Debug.Log(speed); // works
}
}
You're trying to access an instance member inside a static method. That's not allowed. You can define k as static to make it work
static Test k = new Test();
I recommend you to take a look to Static Classes and Static Class Members to get more details
The static member is callable on a class even when no instance of the class has been created. The static member is always accessed by the class name, not the instance name. Only one copy of a static member exists, regardless of how many instances of the class are created. Static methods and properties cannot access non-static fields and events in their containing type, and they cannot access an instance variable of any object unless it is explicitly passed in a method parameter.
In addition to the other answers, another option is to make your Test class and Rt method static. Like so:
public class Program
{
public static void Main()
{
Console.Write(Test.Rt());
}
}
public static class Test {
public static int Rt() {
return 10;
}
}
You really don't have many cases to use a static class though they do exist. I would just move Test t = new Test(); inside your Main method.
public class Program
{
public static void Main()
{
Test t = new Test();
Console.Write(t.Rt());
}
}
public class Test {
public int Rt() {
return 10;
}
}
This is because your Main method is static but your Test2 class is not static. The k variable lives in an instance of Test2 but the Main method belongs to the type itself. If something is static, it means you can call it without instantiating a variable of that type:
Test2.Main();
If you attempted to instantiate a Test2 and call Main you'd get an error because it's static.
var test2 = new Test2();
test2.Main(); //ERROR
You can make k static for this to compile:
public class Test2 {
// initialize constructor here, but return compile-error
static Test k = new Test();
static void Main() {
Console.Write(k.Rt()); // error here
}
}
The second example you showed works fine because the Update method is not static, which means that the method lives with an instantiation of PlayerScript, unlike the Main method.

Cannot access a non-static member of outer type via nested type

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.

In a private class : access to a member of the "outer class"?

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;
}

Nested class - calling the nested class from the parent class

I have a class whereby a method calls a nested class. I want to access the parent class properties from within the nested class.
public class ParentClass
{
private x;
private y;
private z;
something.something = new ChildClass();
public class ChildClass
{
// need to get x, y and z;
}
}
How do I access x,y and z from within the child class? Something to do with referencing the parent class, but how?
Use the this keyword to pass a reference to 'yourself' to the constructor of the ChildClass.
public class ParentClass
{
public X;
public Y;
public Z;
// give the ChildClass instance a reference to this ParentClass instance
ChildClass cc = new ChildClass(this);
public class ChildClass
{
private ParentClass _pc;
public ChildClass(ParentClass pc) {
_pc = pc;
}
// need to get X, Y and Z;
public void GetValues() {
myX = _pc.X
...
}
}
}
See http://www.codeproject.com/KB/cs/nested_csclasses.aspx for a detailed tutorial on using nested classes in C#. I think you're looking for something like:
class OuterClass
{
public int y = 100;
public class NestedClass
{
public static void abc()
{
OuterClass oc = new OuterClass();
System.Console.WriteLine(oc.y);
}
}
}
So, in order to access the fields of the outer class, you need an instance of the outer class available to the inner class.
Keep in mind that you can access static fields from the inner class without an instance of the outer class around:
class OuterClass
{
public static int y = 100;
public class NestedClass
{
public static void abc()
{
System.Console.WriteLine(OuterClass.y);
}
}
}
You need to pass in a reference to the parent class instance, for instance in the constructor of ChildClass. Of course you can access fields of ParentClass if those are static.
Note: If you have ever done Java, C# only supports the notion of the "static" inner class.
Well, on the constructor of your nested class pass in a reference to the outer class.
That way you can access the parent class properties from within the nested class.
Also, it's worth noting that static properties from the parent class, are available to you.
http://en.csharp-online.net/Nested_Classes
Example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Application {
class OuterClass {
int someProperty = 10;
class NestedClass {
OuterClass reference;
public NestedClass( OuterClass r ) {
reference = r;
}
public void DoSomething( ) {
Console.Write( reference.someProperty );
}
}
public OuterClass( ) {
NestedClass nc = new NestedClass( this );
nc.DoSomething( );
}
}
class Test {
public static void Main( string[] args ) {
OuterClass oc = new OuterClass( );
}
}
}

Categories