c# Accessing Creation Class Variables From Instance - c#

Just a basic programming question.
public class ClassA
{
int i = 10;
void Start()
{
ClassB b = new ClassB(this);
b.DoSomething();
}
}
public class ClassB
{
ClassA a;
public ClassB(ClassA a)
{
this.a = a;
}
void DoSomething()
{
Console.WriteLine(a.i);
}
}
I would really like to omit the a:
Console.WriteLine(a.i);
->
Console.WriteLine(i);
What is the most reasonable method of achieving this?
(Note: ClassB must not inherit from ClassA, as ClassA inherits from something ClassB cannot. And I suppose I should say I don't want to pass parameters to the functions, so DoSomething(i) is not applicable.)

You can create a property. Please note that a.i still needs to be public for both your example and mine.
public class ClassB
{
private ClassA a;
public ClassB(ClassA a)
{
this.a = a;
}
public int i { get { return a.i; } }
void DoSomething()
{
Console.WriteLine(i);
}
}

Related

Pattern to avoid the need for Downcasting/Reflection

Suppose I have two implementations of a base class:
public class Base {
public string Stringify() { return "I am a member of base class"; }
}
public class A : Base {
public void DoAThing() {...};
}
public class B : Base {
public void DoBThing(int anInteger) {...};
}
Suppose I want to put many instances of Base in a list, so that I can loop over them and call Stringify() on each, and make use of their shared functionality.
static void Main(string[] args)
{
A thing1 = new A();
B thing2 = new B();
B thing3 = new B();
List<Base> list = new List<Base> {thing1, thing2, thing3};
foreach(Base base in list) { Console.WriteLine(base.Stringify()); }
}
Now suppose there are many many Base objects, such that maintaining the individual thing references to each one is not realistic. Would there be any way, via only the list, to regain the DoAThing() or DoBThing() functionality that is lost by the abstraction without having to use explicit downcasting and reflection?
This feels like it would be a common enough occurance, so I am wondering if there is a design flaw or established pattern I am missing here that would help in this situation.
If you debug, you can notice every object of the list mantains its' class.
This way:
class Program
{
static void Main(string[] args)
{
A thing1 = new A();
B thing2 = new B();
B thing3 = new B();
List<Base> list = new List<Base> { thing1, thing2, thing3 };
foreach (Base bas in list) {
Console.WriteLine(bas.Stringify());
if(bas is A)
{
((A)bas).DoAThing();
}
else if (bas is B)
{
((B)bas).DoBThing(1);
}
else
{
//IDK
}
}
}
}
public abstract class Base
{
public string Stringify() { return "I am a member of base class"; }
}
public class A : Base
{
public void DoAThing()
{
}
}
public class B : Base
{
public void DoBThing(int anInteger)
{
}
}

nested classes and interfaces

(I really struggled with coming up with a good title for this question, if anyone wants to help out with that..)
So I'm having an issue designing something. Essentially I have a class A, which is composed of an array of objects of type B. I only want the interface of class A to be exposed, and want to keep class B essentially hidden to any user. I want to be able to perform operations on type B and its data, but only through class A's interface/methods calling methods of an instance of B. The part where it gets tricky is that I want to create a method that performs operations on members of type B, but I wanted to implement an interface and then have a class that implements that interface because I want my user to be able to create their own implementation of this method. I was thinking of doing somtehing like:
public class A
{
B[] arr;
C c;
public A(C c)
{
arr = new B[100];
this.c = c;
}
public void method1()
{
var b = new B();
b.someMethodofb(c); // pass c to the method of b
}
private class B
{
someMethodOfb(C c)
{
}
}
}
public class C : Interface1
{
public void method(B b)
{
//interface method we have implemented
}
}
I made the class B private because I only want class A to be publicly available so anything that happens to class B happens through class A, which is also why I nested B within A. But since class B is private, will I be able to use it as a parameter for the method of my class C? The method of Interface1 implemented is going to affect the internal implementation of how B performs someMethodOfb, which is why I think I need to pass it in to be able to maintain the hidden nature of class B. Could there be a better way for me to design this and be able to achieve the goals I set out in the first paragraph?
I would suggest you add another interface for the public known side of B, have B implement that interface and have C's method(s) use the interface.
public interface IC {
void method(IB b);
}
public interface IB {
int Priority { get; set; }
int Urgency { get; set; }
}
public class A {
B[] arr;
IC c;
public A(C c) {
arr = new B[100];
this.c = c;
}
public void method1() {
var r = (new Random()).Next(100);
arr[r].someMethodOfB(c); // pass c to the method of b
}
private class B : IB {
public int Priority { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public int Urgency { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
internal void someMethodOfB(IC aC) {
aC.method(this);
throw new NotImplementedException();
}
}
}
public class C : IC { // user implements
public void method(IB b) {
if (b.Priority > 10 || b.Urgency > 10)
; // do something with BI using b
throw new NotImplementedException();
}
}
Now the user of the classes needs to know IC so they can create C and they need to know IB so they can write the body of the methods in C, but they don't need to know all of B or have access to B.
Let's use concrete examples :)
Say, we have three classes: Customer, Order, and OrderProcessor. Customer and Order are entities representing a customer and an order respectively, while OrderProcessor will process an order:
public interface IOrderProcessor
{
void ProcessOrder(IOrder order);
}
public interface IOrder
{
void FinalizeSelf(IOrderProcessor oProc);
int CustomerId {get; set;}
}
public class Customer
{
List<IOrder> _orders;
IOrderProcessor _oProc;
int _id;
public Customer(IOrderProcessor oProc, int CustId)
{
_oProc = oProc;
_orders = new List<IOrder>();
_id = CustId;
}
public void CreateNewOrder()
{
IOrder _order = new Order() { CustomerId = _id };
_order.FinalizeSelf(_oProc);
_orders.Add(_order);
}
private class Order : IOrder
{
public int CustomerId {get; set;}
public void FinalizeSelf(IOrderProcessor oProcessor)
{
oProcessor.ProcessOrder(this);
}
}
}
public class ConcreteProcessor : IOrderProcessor
{
public void ProcessOrder(IOrder order)
{
//Do something
}
}

Callback function in c# - WPF

I have class A which define class B:
B b=new B()
I would like to call to a function in class A from B.when I tried to make this function- static- i got an error cause i have in that function-
Dispatcher.BeginInvoke...
Is there another way to do it?
Why not just pass a reference of A to B.
Something like
public class A
{
public A()
{
B b = new B(this);
}
}
public class B
{
public B(A a)
{
}
}
Or you could make it a property of B.
Something like
public class A
{
public A()
{
B b = new B
{
MyA = this
};
}
}
public class B
{
public A MyA;
}

OpCodes.Castclass. Is it necessary?

Is it necessary to emit OpCode.CastClass(typeof(A)) when you having a reference to instance of (B) on top of stack, where B is class, derived from A, when preparing for a call to method with argument of type A?
Addition:
interface IFoo
{
void IFoo();
}
public class A:IFoo
{
public void IFoo()
{
}
}
public class B:A,IFoo
{
new public void IFoo()
{
}
}
var b = new B();
(b as IFoo).Foo();
((b as A) as IFoo).Foo();
I guess you have something like this:
class A
{
public void Foo() { }
}
class B : A
{
}
and need to decide between:
B b = new B();
b.Foo();
and
B b = new B();
((A)b).Foo();
Both work. But the cast is not necessary, because B inherits all members from A.

access property value of one class from another internal class in C#

how do i acces the property value from an internal class , see below?
namespace N1
{
public class ClassA
{
string var1 = null;
private ClassB b;
public ClassA()
{
var1 = "one";
b = new ClassB();
}
//property
public string Var1
{
get{ return var1; }
}
}
namespace N1
{
internal class ClassB
{
private void method()
{
// I need to access the value of Var1( property) from here, how to do this?
}
}
}
Pass an instance of ClassA into ClassB's constructor:
namespace N1
{
internal class ClassB
{
private ClassA _classAInstance;
public void ClassB(ClassA classAInstance)
{
_classAInstance = classAInstance;
}
private void method()
{
// You can access _classAInstance properties here
}
}
}
Update: I missed that a ClassB instance b was a private member on ClassA. Using my previous answer, you can just instantiate b in ClassA's constructor:
public ClassA()
{
var1 = "one";
b = new ClassB(this);
}
You need a reference to an instance of Class A.
So either change Class B constructor to accept a reference to class A
namespace N1
{
public class ClassA
{
string var1 = null;
private ClassB b;
public ClassA()
{
var1 = "one";
b = new ClassB(this);
}
//property
public string Var1
{
get { return var1; }
}
}
}
namespace N1
{
internal class ClassB
{
ClassA classA;
public ClassB(ClassA classARef)
{
classA = classARef;
}
private void method()
{
// I need to access the value of Var1( property) from here, how to do this?
string myString = classA.Var1;
}
}
}
or make ClassB's private method() take in a string? private void method(string classAVar1)
or make ClassA static (haha)
Well there are a couple of ways:
Change the access modifier of ClassB.Method to be public and make it take a string parameter.
Update the constructor of ClassB to take a string parameter and store it in a private field.
Add a public string property to ClassB.
Making a class internal just means the class is only available with files inside the same assembly.
You can't. Change access modifiers of either class A or B.
Purpose of internal class is to contain some internal logic implementation, and if you have need to access public classes' fields from it, probabli something wrong with app design

Categories