Calling Object properties from different classes in C# - c#

I have created an object that holds 4 properties, and will get created and used in Class A. However, I need to call some of the properties in 2 other classes (Class B and Class C). I'm not able to do this, and I'm confident that I am missing something very simple. Here is my object creation class:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
public class ConfigItems
{
public static string W { get; set; }
public static string X { get; set; }
public static int Y { get; set; }
public static Int64 Z { get; set; }
public ConfigItems(string w, string x, int y, Int64 z) {
W= w;
X= x;
Y= y;
Z= z;
}
}
}
In my Main class, this is how I'm creating the object, which works just fine as long as I remain in the Main class:
namespace Test
{
public class Main
{
ConfigItems mainSetup = new ConfigItems(w, x, y, z);
console.writeline(mainSetup.x);
}
}
In the Main class when I create the object, I can keep calling it. When I move to a new class and try to call the same object, I cannot. It is out of scope, and I'm not certain as to why.
namespace SomeClass
{
public class StuffHere
{
Console.Writeline(mainSetup.x);
}
}
mainSetup.x in the above will not return anything, because it is out of scope. I have tried using both static and non-static properties in the object creation lass (ConfigItems) but I still can't call mainSetup.x outside of the Main class

You have defined your properties as static, therefore they are not instance members, but members of the class. Remove the static keyword.
public string X { get; set; }

Your class is not static! so you can't access class's property directly.
You have two way:
Make your class static.
public static class ConfigItems {
}
Pass the class context from initialer class (A) to other classes (B or C).
Class A:
ConfigItems mainSetup = new ConfigItems(w, x, y, z);
SecondClass b = new SecondClass(mainSetup);
Class B or C:
public class SecondClass {
public SecondClass (ConfigItems config) {
// You have the ConfigItems class here and you can do anything with it
}
}

you can access them directly using CalssName
ConfigItems.X;

Related

C# public property get accessor inaccessible from another namespace

I have tried making the field public itself; I have also tried using public get, even if, as I understand, access modifiers inside a property will only have effect if more restrictive. Yet I wasn't able to access the 'problem.Points'(last line) property from the TestUnit. I get an "get accessor inaccessible" alert. Notice that I'm able to access it from another class in the same namespace. I must be missing something very basic here.
namespace Coordinates_Path
{
public interface IProblem
{
abstract public List<Node> Points { get; set; }
abstract public Object GetStartState();
abstract public bool IsGoalState();
abstract public Object GetSuccessor();
}
public class ShortestPathThroughCoordinates : IProblem
{
private Node startState;
private List<Node> points;
public List<Node> Points { get { return points; } private set; }
//...
//...
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Coordinates_Path;
using System.Linq;
using System.Collections.Generic;
namespace CoordPathTest
{
[TestClass]
public class KruskalTest
{
[TestMethod]
public void TestMST()
{
// ...
IProblem problem = new ShortestPathThroughCoordinates("P1", coordDic);
MSTKruskal kruskal = new MSTKruskal(problem.Points)
If you look at
public class ShortestPathThroughCoordinates : IProblem
{
public List<Node> Points { get { return points; } private set; }
...
all referenced classes must be visible to the calling assembly. Check to ensure that Node is also visible.
Change your interface to this:
public interface IProblem
{
List<Node> Points { get; set; }
Object GetStartState();
bool IsGoalState();
Object GetSuccessor();
}
Interfaces only define public members so you do not have to declare it. All members of an interface must be implemented so there is also no need to declare them as abstract.
Unless private List points; is set somewhere further down in the code that we can't see you are never initializing this variable so your get will be null;

abstract class constructor inheritence with inner classes objects

Let s say I got an abstract class A. There I got some inner classes like here:
public abstract class A
{
public InnerOne x;
public InnerTwo y;
public A(){
this.x = new InnerOne();
this.y = new InnerTwo();
}
public class InnerOne
{
public virtual double value(){
return 0;
}
}
public class InnerTwo
{
public virtual double value(){
return 0;
}
}
}
Then I got it's childrens like this one:
public class B: A
{
public B():base(){
}
public class InnerOne: A.InnerOne
{
public override virtual double value(){
return 100;
}
}
public class InnerTwo: A.InnerTwo
{
public override virtual double value(){
return 100;
}
}
}
So I was think that when I call B constructor like that I will initialize x and y by creating it's inner classes instances. But actually it not works like that. When I call vaule functions like here it returns zeros.
A newobject = new B();
var bv1 = B.x.value();
var bv2 = B.y.value();
Is there way to force B class to initialize it's x and y fields by it's inner class objects (not with objects from parent abstract class) without re-writing it's constructor?
Even though you have defined the classes inside A or B, they are still public and they are accessible outside A or B. Its no different from a class definied outside A or B.
Imagine the same code with the InnerOne and InnerTwo defined outside the class A and B. It will have the same above behavior. Your root of confusion is misunderstanding inner class usage.
Inorder to get 100, inside B you need to explicitly replace the instance of X and Y variables with an instance that overrides those values. Unless you do them you will not get 100.
public class B: A
{
public B():base(){
X = new OverridenInnerOne();
Y = new OverridenInnerTwo();
}
public class OverridenInnerOne: A.InnerOne
{
public override virtual double value(){
return 100;
}
}
public class OverridenInnerTwo: A.InnerTwo
{
public override virtual double value(){
return 100;
}
}
}
You can do it, but you must change the definition for class A - and it gets super hairy.
Here's A:
public abstract class A<I1, I2>
where I1 : A<I1, I2>.InnerOne, new()
where I2 : A<I1, I2>.InnerTwo, new()
{
public InnerOne x;
public InnerTwo y;
public A()
{
this.x = new I1();
this.y = new I2();
}
public class InnerOne
{
public virtual double value()
{
return 0;
}
}
public class InnerTwo
{
public virtual double value()
{
return 0;
}
}
}
And here's B:
public class B: A<B.InnerOne, B.InnerTwo>
{
public B():base(){ }
public class InnerOne: A<InnerOne, InnerTwo>.InnerOne
{
public override double value()
{
return 100;
}
}
public class InnerTwo: A<InnerOne, InnerTwo>.InnerTwo
{
public override double value()
{
return 100;
}
}
}
B.x and B.y are instances of A.InnerOne and A.InnerTwo, so you're seeing the value returned as 0 as these have nothing to do with B.InnerOne or B.InnerTwo.
The following B constructor would assign x and y to instances of B.InnerOne and B.InnerTwo which would return 100.
public B(){
this.x = new InnerOne();
this.y = new InnerTwo();
}
If you wanted A to work in the way you expect, you'd need to pass the inner types you wanted through from the B constructor and create instances of them in the A constructor, something like:
public B():base(typeof(InnerOne),typeof(InnerTwo)) { ... }
Using Activator.CreateInstance will let you create these types within A's constructor.
Enigmativity's generic solution is better if you always want A used this way, alternatively this way allows you to have multiple constructors for A so you could optionally pass in different types.
The 'inner class' aspect (embedded class definition) only distracts here, it plays no role.
And to answer the question: No, you cannot have 'virtual constructors' that work this way.
There are of course plenty of ways to get 100 instead of 0 as returnvalue but the question is too artificial to suggest one.

Call inner class in c#?

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.

Working with System.ComponentModel

I am having a bit of difficulty in understanding how the Container/Component model interacts with each other in C#. I get how the Component contains a Site object which has information about Container and Component. But, suppose I had the following code:
using System;
using System.ComponentModel;
public class Entity : Container {
public string Foo = "Bar";
}
public class Position : Component {
public int X, Y, Z;
public Position(int X, int Y, int Z){
this.X = X;
this.Y = Y;
this.Z = Z;
}
}
public class Program {
public static void Main(string[] args) {
Entity e = new Entity();
Position p = new Position(10, 20, 30);
e.Add(p, "Position");
}
}
This works without issue, it defines a Container (Entity) and a Component (Position) that is contained inside it.
However, if I invoke p.Site.Container, it will return Entity, but as IContainer. That is, I would have to explicitly do something like (Console.WriteLine(p.Site.Container as Entity).Foo); if I wanted to access Foo. This seems quite cumbersome.
Am I missing something, or is there a better way to do what I want?
You're not missing anything. There is no interface contract regarding what container a component can be inside. If you want to restrict what kind of components can be added to the container you can overload the Add method and do a check of the type of component being added:
public class Entity : Container {
public string Foo = "Bar";
public virtual void Add(IComponent component) {
if (!typeof(Position).IsAssignableFrom(component.GetType())) {
throw new ArgumentException(...);
}
base.Add(component);
}
}

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