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
Related
I wonder if something like this is possible in C#:
public class A
{
public string Foo() { return "Foo"; }
}
public class B : A
{
public string Bar() { return Foo(); }
}
public class C : B
{
public new string B.Foo() { return "Bar"; } // Hide A.Foo in B
}
Main()
{
C c = new C();
Console.WriteLine(c.Bar()); // Want to get "Bar"
}
by public new string B.Foo() { return "Bar"; } I mean do something in C (without changing A or B) that has the equivalent result as if public new string Foo() { return "Bar"; } was implemented in B. So, hide a method FOR a base class OF a base further up the inheritance hierarchy.
What you want is virtual, which allows you to override base behavior in the inheriting type.
public class A
{
public virtual string Foo() { return "Foo"; }
}
public class B : A
{
public virtual string Bar() { return Foo(); }
}
public class C : B
{
public override string Foo() { return "Bar"; } // Hide A.Foo in B
}
This outputs "bar"
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);
}
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();
Essentially, what we've got is this:
public class A {
...
public A() { ... }
...
}
public class B : A {
...
public B() : base()
{ throw new Exception(); }
...
}
But then:
public class Test<T>
where T : A, new()
{
public void doStuff() { B b = new B(); }
}
And no exception is thrown. It's really quite confusing! Am I missing something?
The following code throws an exception as intended. I imagine you aren't using your Test class correctly since you didn't post the code.
public MainWindow()
{
InitializeComponent();
Test<B> myTest = new Test<B>();
myTest.doStuff(); // throws exception in B()
}
public class A
{
public A() { }
}
public class B : A
{
public B()
: base()
{
throw new Exception();
}
}
public class Test<T> where T : A, new()
{
// I modified this because the intent is to use T correct?
public void doStuff() { T test = new T(); }
}