There are many classes A, B, C and so on.
In each of them, there are some methods:
class A {
void a1() { ...; }
void a2() { ...; }
}
class B { //dll
void b1() { ...; }
void b2() { ...; }
}
class C { //dll
void c1() { ...; }
void c2() { ...; }
}
Class A is coded by me and the Class B and C are an imported dll.
With Class A I can put breakpoints to track, but I can't with Class B anc C.
My program is going to be of hundreds of classes and I'd like to track in what sequential order
methods in each class are called.
Is it possible to output this kind of information even there are methods defined in dll?
Ex. a1 -> b2 -> c1 -> a2
Added:
Especially when a dll method call another dll method.
In this case wrapper would be little help.
Anyone?
If the code comes to you in a DLL with no source or debug symbols, your debug options are rather limited: you cannot set breakpoints with no source, unless you are comfortable looking at disassembly.
One way to address the issue is to wrap the external code in your own class, like this:
class CWrap {
private readonly C wrapped = new C();
public void c1() {
log.Info("Entering c1");
wrapped.c1();
log.Info("Entering c1");
}
public void c2() {
log.Info("Entering c2");
wrapped.c2();
log.Info("Exiting c2");
}
}
Mutltithreading is applied to Methods, not Classes.
Once you start the threads, order is indeterminate. Thread order execution
var a = new A();
var b = new B();
var c = new C();
new Thread(a.a1).Start();
new Thread(b.b1).Start();
new Thread(c.c1).Start();
There is no definite order for a1, b1, c1.
If you like you can pipeline the execution using Tasks .
Tasks.StartNew(()=> a.a1()).ContinueWith(_ => b.b1().ContinueWith(_=>c.c1);
It pipelines execution of a1, b1 and c1.
It makes use of Tasks.ContinueWith
Is it possible to output this kind of information even there are methods defined in dll?
Yes, if you specify debug build
Related
I have simple three classes:
class A
{
public virtual void Write()
{
Console.Write("A");
}
}
class B:A
{
public override void Write()
{
Console.Write("B");
}
}
class C : B
{
public new void Write()
{
Console.Write("C");
}
}
And I am creating objects and calling their methods:
A a = new A();
a.Write();
A b = new C();
b.Write();
C c = new C();
c.Write();
And output will be: ABC
What I cannot understand is why these code produces B?:
A b = new C();
b.Write();
I thought that it should be C. However, I tested many times, and it is always B.
I understand that A b = new C() creates new object type of C. So output should be C. Or it is special behavior to call overridden method when we use it without casting?
Why does it happen? As we have not used any reference to B class.
It would work if you'd use ((C)b).Write();
With the new keyword you're not overriding the Write method for C but rather creating a new method only defined for C. So for your C you actually have 2 methods with a method name Write.
A c = new C();
c.Write(); //Output "B", you're calling the overridden method
((C)c).Write(); //Output "C", you're calling the method defined on C
//or
(c as C).Write();
The same happens when you would define c as C:
C c = new C();
c.Write(); //Output "C"
((A)c).Write(); //Output "B"
In the first example you're calling the new method defined on C. In the second line you are calling the Write method from A, which is overridden by B, hence the output "B".
Edit: (some more explanation)
Variable c is of type A, so that's what your compiler knows "c is an instance of A", it is not known that it is actually of a more derived type. When you call the method Write on it, it will invoke the method defined on A (which is overriden by B). Your base class A has no knowledge of your new method defined on C (that's what new does, create a new method), so unless you cast it to C to let the compiler know about the actual, derived type of c, the method of your base class will be called.
I now its really late and does not answer the question, but i needed that behavior and just in case some else need it i'll share it.
To get that beheavior you need to use interfaces, for example
interface Writer{
void write;
}
class A : Writer
{
void Writer.Write()
{
Console.Write("A");
}
}
And the same for the others. As you can see, you have to implement it explicity as well as call it explicity.
A c = new C();
((Writer) c).write()
;
I have simple three classes:
class A
{
public virtual void Write()
{
Console.Write("A");
}
}
class B:A
{
public override void Write()
{
Console.Write("B");
}
}
class C : B
{
public new void Write()
{
Console.Write("C");
}
}
And I am creating objects and calling their methods:
A a = new A();
a.Write();
A b = new C();
b.Write();
C c = new C();
c.Write();
And output will be: ABC
What I cannot understand is why these code produces B?:
A b = new C();
b.Write();
I thought that it should be C. However, I tested many times, and it is always B.
I understand that A b = new C() creates new object type of C. So output should be C. Or it is special behavior to call overridden method when we use it without casting?
Why does it happen? As we have not used any reference to B class.
It would work if you'd use ((C)b).Write();
With the new keyword you're not overriding the Write method for C but rather creating a new method only defined for C. So for your C you actually have 2 methods with a method name Write.
A c = new C();
c.Write(); //Output "B", you're calling the overridden method
((C)c).Write(); //Output "C", you're calling the method defined on C
//or
(c as C).Write();
The same happens when you would define c as C:
C c = new C();
c.Write(); //Output "C"
((A)c).Write(); //Output "B"
In the first example you're calling the new method defined on C. In the second line you are calling the Write method from A, which is overridden by B, hence the output "B".
Edit: (some more explanation)
Variable c is of type A, so that's what your compiler knows "c is an instance of A", it is not known that it is actually of a more derived type. When you call the method Write on it, it will invoke the method defined on A (which is overriden by B). Your base class A has no knowledge of your new method defined on C (that's what new does, create a new method), so unless you cast it to C to let the compiler know about the actual, derived type of c, the method of your base class will be called.
I now its really late and does not answer the question, but i needed that behavior and just in case some else need it i'll share it.
To get that beheavior you need to use interfaces, for example
interface Writer{
void write;
}
class A : Writer
{
void Writer.Write()
{
Console.Write("A");
}
}
And the same for the others. As you can see, you have to implement it explicity as well as call it explicity.
A c = new C();
((Writer) c).write()
;
i have piece of code
public class A
{
public A()
{
Console.WriteLine("A");
}
B b = new B("From A");
}
public class B : A
{
public B()
{
Console.WriteLine("B");
}
public B(string str) //Getting exception here
{
Console.WriteLine("In B " + str);
}
}
public class C : A
{
B b = new B("From C");
public C()
{
Console.WriteLine("C");
}
}
class Program
{
static void Main(string[] args)
{
new C();
Console.ReadKey();
}
}
Here, i know that all properties are initialized first before base constructor called, but i am unable to find why i am getting Stackoverflow exception. Any Help ?? Thanks
Because B inherits from A, it inherits the
B b = new B("From A");
field. So whenever you create a B object it creates another B object, in an infinite recursive chain.
So in the actual Program you have, you create a C object. This then constructs a B object using the overload that takes a string ("From C"). You then get an exception on that constructor, because it then recursively creates infinite B objects.
Recursive infinite loop:
Every time you create a B, you create a new A (through inheritance).
Every time you create an A, you create a new B (through variable b).
Since B inherits from A
//public class B : A
And when you create object of B in class A,It goes in recursive infinite loop.
The problem above is due to cyclic instantiation.
Here our thinking of instantiation causes these kind of issues:
Here when we instantiate C we just do not get object of class C but, it in fact is the combination of C+B+A.
These kind of problems can be easily identified by drawing an object diagram with Arrows from instantiating object to instanted object.
I have following design problem programming application in C#.
I have classes A and B that both derives from C. I cannot change theirs definition because they are defined in external assembly and are not defined as partial too.
What I am trying to achieve is to differ functionality basing on weather provided C object is of type A or B. Of course I dont want to use if statements comparing runtime types of provided object. Is it possible with extensions methods? I dont think so.
Any solution? :)
It should be possible with extension methods by using generics.
Multiple approaches are possible, but this one is simplest. Although you do get that if
public static void Foo<T>(this T objectC)
where T: C
{
if(typeof(T)==typeof(B){ //or for runtime check: if(objectC is B)
//specific
}
}
you could then call Foo on any instance of A or B.
You mention you donĀ“t want if statements, but I'm not sure to which extend you're trying to avoid that? The only way to completely avoid it, is to have 2 extension methods, one for A and one for B, (which in turn can call a common method for C), but I think you're trying to avoid multiple extension methods?
edit If you absolutely want to prevent if's, you'll have to use multiple extension methods as shown in Frederik's post. You could add an extension for the baseclass as well, that only gets called if the type is not known during compilation. But that would still need an if ;)
public static void Foo(this A a)
{
}
public static void Foo(this B b)
{
}
public static void Foo(this C c)
{
if(c is A)
Foo((A)c);
else if(c is B)
Foo((B)c);
else
throw new NotSupportedException(c.GetType().FullName);
}
If the type is always known at compile time, you can simply use the 2 extension methods for A en B.
You could try this:
public static class CExtensions {
public static void DoIt( this B foo ) {}
public static void DoIt( this A foo ) {}
}
But, I don't think that this will work:
C x = new A();
x.DoIt();
I don't think it will compile, but, I can't test it right now.
Purely from a feasibility point of view, it is possible using reflection and extension methods. Whether it makes sense in the context of your application, is something you should judge. Here goes the solution....
class C
{
}
class A : C
{
}
class B : C
{
}
static class Extender
{
public static void M(this B b)
{
Console.WriteLine(" Extension method on B");
}
public static void M(this A a)
{
Console.WriteLine(" Extension method on A");
}
}
static void Main(string[] args)
{
C c = new A();// The actual instance here will be created using some factory.
object instance = Activator.CreateInstance(c.GetType());
Type typeToFind = c.GetType();
Type typeToQuery = typeof(Extender);
var query = from method in typeToQuery.GetMethods(BindingFlags.Static
| BindingFlags.Public | BindingFlags.NonPublic)
where method.IsDefined(typeof(ExtensionAttribute), false)
where method.GetParameters()[0].ParameterType == typeToFind
select method;
// You would be invoking the method based on its name. This is just a quick demo.
foreach (MethodInfo m in query)
{
m.Invoke(instance, new object[] { instance });
}
}
To me this feels like a flaw in design.
If you can't have a common class to two sub classes which override and changes functionality without knowing the run time type you clearly have some issues with the overall design.
Should that functionality that differ depending on run time types really reside in those classes at all?
You could do it this way. Create a class with the different methods you need. In the same class define a delegate with the signature of this methods and keep a Dictionary where the keys are the types, and the values the delegates. Finally you can create an extension method for your class C that look into the dictionary using the type of the object that's executing the method itself and executes the right method. Something like this:
public static class CExtender
{
private static void DoItA(C anA)
{
MessageBox.Show("A");
}
private static void DoItB(C aB)
{
MessageBox.Show("B");
}
private static void DoItC(C aC)
{
MessageBox.Show("C");
}
delegate void DoItDel(C aC);
private static Dictionary<Type, DoItDel> _doItDels;
private static Dictionary<Type, DoItDel> DoItDels
{
get
{
if (_doItDels == null)
{
_doItDels = new Dictionary<Type, DoItDel>();
_doItDels[typeof(A)] = new DoItDel(DoItA);
_doItDels[typeof(B)] = new DoItDel(DoItB);
}
return _doItDels;
}
}
// the only public part is the extension method
public static void DoIt(this C aC)
{
DoItDel aDel;
if (DoItDels.TryGetValue(aC.GetType(), out aDel))
aDel(aC);
else
DoItC(aC);
}
}
You can use Decorater pattern in this case.
i.e. you can have 2 new classes of your own let say A1, B1 both deriving from C. (provided C is not a sealed class. If that's the case solution would be a bit different). Also A1 and B1 needs to wrap A and B corespondingly. You could inject instances of A and B through the constructors of A1 and B1.
You can also have a common interface which A1 and B1 both implmement. Interface needs to have the method which you need A1 and B1 to implement in their own ways. (A1 and B1 can delegate the calls to A or B as needed)
This way, in your client code, you can refer to A1 and B1 instances by their interface type and perform the common operation defined in the interface without knowing what their actual concrete implementations are.
Let me know if you need a code sample if I wasn't clear.
OK I found the answer.
The dynamic keyword is the clue here.
We can write:
void Handle(C c)
{
dynamic cc = c;
HandleSpecific(cc);
}
void HandleSpecific(A a)
{
//Specific behavior A
}
void HandleSpecific(B b)
{
//Specific behavior B
}
Drawbacks are of course - Risk of exception beacause of runtime binding introduced here and slight performance hit.
I have a legacy application where the method calls go several layers deep:
public void A()
{
B();
}
public void B()
{
C();
D();
}
public void C()
{
E();
}
And so on and so forth. Are there any plugins that can show me graphically the methods that are called, so that I can see something like this:
A
-> B
-> C
-> D
-> E
I would suggest looking at Microsoft's CLR Profiler