The current program results in stackoverflow exception which i know why. How could I avoid the circular dependency here. How can i make the three classes independent of each other though the classes are dependent to each other(just imagine that the methods inside those classes refer each other).
namespace CircularDependency_1
{
class Program
{
static void Main(string[] args)
{
A a = new A();
B b = new B();
Console.WriteLine("executed");
Console.ReadLine();
}
}
public class B
{
public A a;
public B()
{
a = new A();
Console.WriteLine("Creating B");
}
}
public class A
{
public B b;
public A()
{
b = new B();
Console.WriteLine("Creating A");
}
}
public class C
{
public A a;
public B b;
public C ()
{
a = new A();
b = new B();
Console.WriteLine("Creating C");
}
}
}
You should not be new'ing up your objects. Instead, you need to pass them as arguments to the constructor. You need to refactor your code to:
public class A {
B _b;
public A(B b) {
_b = b;
Console.WriteLine("Creating A");
}
}
public class B {
A _a;
public B(A a) {
_a = a;
Console.WriteLine("Creating B");
}
}
public class C {
A _a;
B _b;
public C (A a, B b) {
_a = a;
_b = b;
Console.WriteLine("Creating C");
}
}
Then you need to refactor functions out of A (or B) into another class D:
public class A {
D _d;
public A(D d) {
_d = d;
Console.WriteLine("Creating A");
}
}
public class B {
A _a;
D _d;
public B(A a, D d) {
_a = a;
_d = d;
Console.WriteLine("Creating B");
}
}
public class C {
A _a;
B _b;
public C (A a, B b) {
_a = a;
_b = b;
Console.WriteLine("Creating C");
}
}
public class D {
public D () {
Console.WriteLine("Creating D");
}
}
You can then create objects as
D d = new D();
A a = new A(d);
B b = new B(a, d);
C c = new C(a, b);
Console.WriteLine("executed");
Console.ReadLine();
See Circular Dependency in constructors and Dependency Injection on how to refactor your classes to remove circular references
That's not dependency injection, you are creating it in the constructor.
You should keep the A and B constructors empty, and do something like this in C:
public class C
{
public A a;
public B b;
public C ()
{
a = new A();
b = new B();
a.setB(b);
b.setA(a);
}
}
In the other hand, you should check if you really need to have this double reference.
EDIT:
I see that you are not really using class C. If you want to do it in main, is the same thing:
static void Main(string[] args)
{
A a = new A();
B b = new B();
a.setB(b);
b.setA(a);
}
Related
Consider following code:
public class A
{
public A(){}
}
public class B:A
{
public B(){}
}
public class C
{
public C(){}
public void fun(A a)
{
Console.WriteLine("that was A");
}
public void fun(B b)
{
Console.WriteLine("that was B");
}
}
public class Program
{
public static void Main()
{
A a = new A(), b = new B();
C c = new C();
c.fun(a);
c.fun(b);
}
}
In the current form, it says "that was A" twice. How to fix class C, so that fun(B b) is invoked when b's runtime type is B, but compilation type is A? Currently it works properly only when I declare b as B during compilation.
#Edit: without checking types with ifs etc.
Invoke fun via a virtual method.
public class A
{
public virtual void fun(C c)
{
c.fun(this);
}
}
public class B:A
{
public override void fun(C c)
{
c.fun(this);
}
}
public class C
{
public void fun(A a)
{
Console.WriteLine("that was A");
}
public void fun(B b)
{
Console.WriteLine("that was B");
}
}
public class Program
{
public static void Main()
{
A a = new A(), b = new B();
C c = new C();
a.fun(c);
b.fun(c);
}
}
Output:
that was A
that was B
See example on Fiddle
I have the abstract class shown below. It's nested class B is where I would like to define new functions.
public abstract class A {
public string varA = "Default";
public class B {
public B() {
}
public abstract somethingCool(int[] val);
}
}
public class C:A {
//set B functions
}
Is there a particular reason you NEED B to be a nested class? Why not just let your A class have a property of type B? Also, the somethingCool method needs a return type.
public abstract class A
{
public string varA = "Default";
public B InstanceOfB { get; set; }
}
public abstract class B
{
public abstract void SomethingCool(int[] val);
}
public class C : A
{
public override void SomethingCool(int[] val)
{
//do something cool
}
}
I'm not sure what you are trying to do, but if you want to implement B's functions from C, then mark B as abstract and subclass it in C. You can then override the abstract somethingCool method. Something like this:
public abstract class A
{
public string varA = "Default";
public abstract class B
{
public B() {}
public abstract void somethingCool(int[] val);
}
public void Foo(B bar, int[] val)
{
bar.somethingCool(val);
}
}
public class C : A
{
// set B functions
public class D : A.B
{
public override void somethingCool(int[] val)
{
for (int i = 0; i < val.Length; ++i)
{
System.Console.Write(string.Format("{0} ", val[i]));
}
}
}
}
Note that you can also subclass B from outside C:
public class E : A.B
{
public override void somethingCool(int[] val)
{
for (int i = val.Length - 1; i >= 0; --i)
{
System.Console.Write(string.Format("{0} ", val[i]));
}
}
}
Results:
public class Test
{
public void Test()
{
int[] val = new int[] { 1, 2, 3 };
var C = new C();
var D = new C.D();
C.Foo(D, val); // should print 1 2 3
var E = new E();
C.Foo(E, val); // should print 3 2 1
}
}
I have following code:
public class A
{
public int MyProperty {get; set;}
}
public class B
{
A myInstance = new A();
myInstance.MyProperty = 10;
}
public class C
{
public void InvokeA()
{
//How to access MyPropery here?
BInstance = new B();
Console.WriteLine(B.myInstance.MyProperty.ToString());
}
}
I'm looking for a way to access MyProperty as written above. Inheritance is not an option since my class C is already inherited from some base class. A way without declaring any of the given classes as static would be nice!
Thanks,
Orz
Consider following classes:
public class A
{
public int MyProperty { get; set; }
}
public class B
{
public A GetAInstance()
{
A myInstance = new A();
myInstance.MyProperty = 10;
return myInstance;
}
}
public class C
{
private B BInstance;
public void InvokeA()
{
BInstance = new B();
Console.WriteLine(BInstance.GetAInstance());
}
}
and then you will create your C instance in Main:
static void Main(string[] args)
{
C cInstance = new C();
cInstance.InvokeA();
}
In order to accomplish your goal, you need to expose B.MyInstance as a property of the B class, just like you exposed A.MyProperty as a property of the A class.
Edit: Per the comments of others regarding use of the static keyword, here's what you might want your code to look like:
public class A
{
public int MyProperty { get; set; }
}
public static class B
{
static B()
{
MyInstance = new A();
MyInstance.MyProperty = 10;
}
public static A MyInstance { get; set; }
}
public class C
{
// not sure what your intention is here
public C()
{
System.Console.WriteLine(B.MyInstance.MyProperty.ToString()); // "10\n"
}
}
Yes. You can inherits classes from A to B something like this:
public class A
{
public int MyProperty {get; set;}
}
public class B : A
{
public B()
: A()
{
MyProperty = 1;
}
}
Now you can do:
(new B()).MyProperty
Or use Singleton approach to resolve:
public class B
{
private static _a;
public class A
{
public int MyProperty {get; set;}
}
public static A AA {
if (_a == null) {
_a = new A();
}
return _a;
}
}
This implmentation will return
B.A.MyProperty.ToString();
Here's a simple class and a derived class:
class A { public int val; }
class B : A { }
I'd like a method Inc which works on both A and B instances that returns a new instance with val incremented by 1.
One way to approach this is to define Inc as an extension method:
static class Extensions
{
public static T Inc<T>(this T obj) where T : A, new()
{
return new T() { val = obj.val + 1 };
}
}
This seems to work. In the following example, a0.val is 11 and b0.val is 21.
var a = new A() { val = 10 };
var b = new B() { val = 20 };
var a0 = a.Inc();
var b0 = b.Inc();
My question is, is there a way to define Inc as a direct member of A and have it work as above?
If I define A like this:
class A
{
public int val;
public T Inc<T>() where T : A, new()
{
return new T() { val = val + 1 };
}
}
I then need to qualify the type when I call Inc:
var a = new A() { val = 10 };
var b = new B() { val = 20 };
var a0 = a.Inc<A>();
var b0 = b.Inc<B>();
Is there a way to go the member method route without having to qualify the type?
I don't think it's possible without implementing a new version of the method on each subclass, i.e,:
class A
{
public int val;
public virtual A Inc()
{
return new A { val = val + 1 };
}
}
class B : A
{
public new B Inc()
{
return new B { val = val + 1 };
}
}
So, you practically want to create clone of object with different value for some field:
class A {
public int val;
protected virtual A CloneInternal() {
return (A)MemberwiseClone();
}
public A Inc() {
A a=CloneInternal();
++a.val;
return a;
}
}
class B:A {
public new B Inc() {
return (B)base.Inc();
}
}
static void Main() {
A a=new B();
a=a.Inc();
Console.WriteLine(a.GetType());
}
Neither I don't think it's possible. You should provide a hint in order to make compiler guesses proper type for T.
You might try with static method:
public static T Inc<T>(T source) where T : A, new()
{
return new T() { val = source.val + 1 };
}
Then,
var b = new B { val = 20 };
var b0 = A.Inc(b);
But it's not an answer since you wanted a member method. I would rather go with extensions method.
abstract class Base
{
public int val { get; set; }
public virtual Base Inc() { return null; }
}
class A : Base
{
public override Base Inc()
{
return new A { val = val + 1 };
}
}
class B : A
{
public override Base Inc()
{
return new B { val = val + 2 };
}
}
Maybe using a abstract base class is better....
Base bClass = new B();
B bInc = bClass.Inc() as B;
One more way
interface IInc
{
int val { get; set; }
IInc GetNew();
}
class A : IInc
{
public int val
{
get;
set;
}
public virtual IInc GetNew()
{
return new A();
}
public IInc Inc()
{
var newObj = GetNew();
newObj.val++;
return newObj;
}
}
class B : A
{
public override IInc GetNew()
{
return new B();
}
}
and use like
var a = new A() { val = 10 };
var b = new B() { val = 20 };
var a0 = a.Inc();
var b0 = b.Inc();
Console.WriteLine(a0.val);
Console.WriteLine(b0.val);
I have implemented a class as below:
public class Person
{
public int d, e, f;
public Person()
{
}
public Person(int a)
{
}
public Person(int a, int b)
{
new Person(40, 6, 8);
}
public Person(int a, int b, int c)
{
d = a; e = b; f = c;
}
}
public class Program
{
static void Main(string[] args)
{
Person P = new Person(100, 200);
Console.WriteLine("{0},{1},{2}", P.d, P.e, P.f);// it prints 0,0,0
}
}
Now if I create the instance of Person class with two arguments I am unable to set the values of d,e,f which is because in the third constructor a new object of Person is declared all together.
So the previous object does not have any idea about this new one.
Is there any way I can get hold of this new object and assign values to d,e,f from there?
I think you're actually trying to chain constructors together, so that one constructor passes arguments to another:
public Person(int a, int b) : this(40, 6, 8)
{
}
It's odd that you're ignoring a and b though... normally you'd just default one value, e.g.
public Person(int a, int b) : this(a, b, 8)
{
}
See my article on constructor chaining for more details.
public Person()
: this(0,0,0)
{
}
public Person(int a)
: this(a,0,0)
{
}
public Person(int a, int b)
: this(a,b,0)
{
}
public Person(int a, int b, int c)
{
d = a; e = b; f = c;
}
The default value of an int is 0. Use int? and test if it has a value.
e.g.
var d = P.d.HasValue ? P.d : "";
var e = P.e.HasValue ? P.e : "";
var f = P.f.HasValue ? P.f : "";
Console.WriteLine("{0},{1},{2}", d, e, f);
You can write this
public Person(int a, int b)
: this(40, 6, 8)
{
}
to call the other constructor.