> Ben wrote
> > If you need to know when methods are called, you're pretty well out of luck
> > because they could be called virtually using an interface pointer, then the
> > typeref and methodref wouldn't even be to your assembly.
>
> Please explain what you mean... or better yet give an example. The
He means that if you're using dynamic dispatch with polymorphism (aka
virtual methods), you don't necessarily know at compile time (and thus
in the assembly) which actual method will be called. You don't know this
because you don't know at compile time the actual type of the instance.
Discovering actual type for all instances requires solving the halting
problem, i.e. impossible.
Another thing not mentioned yet is reflection. Any method might be
called via reflection, and discovering which ones in all cases requires
solving the halting problem.
Here's an example. Trivial static analysis looking for call opcodes
won't find that C is constructed or that its Foo method is called (and
actually, in this case, C.Foo is called statically, not dynamically, due
to runtime generic instantiation in .NET).
---8<---
using System;
class App
{
interface IFoo
{
void Foo();
}
class C : IFoo
{
public void Foo()
{
Console.WriteLine("Foo");
}
}
static void CallFoo<T>()
where T: IFoo, new()
{
new T().Foo();
}
static void Main()
{
CallFoo<C>();
}
}
--->8---
Following IL produced for CallFoo<T>, no C methodref/defs:
---8<---
.method private hidebysig static void CallFoo<.ctor (App/IFoo) T>()
cil managed
{
// Code size 49 (0x31)
.maxstack 2
.locals init (!!T V_0)
IL_0000: nop
IL_0001: ldloca.s V_0
IL_0003: initobj !!T
IL_0009: ldloc.0
IL_000a: box !!T
IL_000f: brfalse.s IL_001c
IL_0011: ldloca.s V_0
IL_0013: initobj !!T
IL_0019: ldloc.0
IL_001a: br.s IL_0021
IL_001c: call !!0
[mscorlib]System.Activator::CreateInstance<!!0>()
IL_0021: stloc.0
IL_0022: ldloca.s V_0
IL_0024: constrained. !!T
IL_002a: callvirt instance void App/IFoo::Foo()
IL_002f: nop
IL_0030: ret
} // end of method App::CallFoo
--->8---
Only type token required for Main method (in executable metadata
tables):
---8<---
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 8 (0x8)
.maxstack 8
IL_0000: nop
IL_0001: call void App::CallFoo<class App/C>()
IL_0006: nop
IL_0007: ret
} // end of method App::Main
--->8---
-- Barry

Signature
http://barrkel.blogspot.com/
kevin - 26 Dec 2007 16:16 GMT
Ben and Berry and Mattias;
Thanks for your time and responses gentleman. I learned something over
these last couple of days. I hope the holiday (whatever your persuasions)
was good to you and yours.
> He means that if you're using dynamic dispatch with polymorphism (aka
> virtual methods), you don't necessarily know at compile time (and thus
> in the assembly) which actual method will be called. You don't know this
> because you don't know at compile time the actual type of the instance.
> Discovering actual type for all instances requires solving the halting
> problem, i.e. impossible.
So what was old is new again. Late Binding returns... and after I was made
to feel ashamed about all that VB6 and ASP code!
So in conclusion, I can filter my app to only be concerned with NewObj,
Throw, Call, Calli and Callvirt, but I should understand that I will run into
a few "dead ends".
Kevin
Jon Skeet [C# MVP] - 26 Dec 2007 16:24 GMT
> > He means that if you're using dynamic dispatch with polymorphism (aka
> > virtual methods), you don't necessarily know at compile time (and thus
[quoted text clipped - 5 lines]
> So what was old is new again. Late Binding returns... and after I was made
> to feel ashamed about all that VB6 and ASP code!
There's a big difference between "hope that there's a method with this
name at runtime" and "know that there's a method with this name, but
evaluate exactly which implementation to call at runtime".
(Of course, dynamic languages are quite popular these days, but usually
there are additional benefits provided, such as being able to react
different to method calls based on their name if no "real" method is
found.)

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Ben Voigt [C++ MVP] - 26 Dec 2007 20:38 GMT
> Ben and Berry and Mattias;
> Thanks for your time and responses gentleman. I learned something over
[quoted text clipped - 16 lines]
> into
> a few "dead ends".
You can be assured that those do depend on the type in question, but that
the type may be used other ways that cannot be determined until runtime.
> Kevin