how are extension methods evaluated? or in a very specific use case: if an extension method is implemented as a class instance method by a new version of an assembly and that assembly is updated but dependent assemblies are not, will they:
- still access the extension method
- access the new class instance method
- throw
I’ve added the following simple code samples of a FooExtensions assembly, an IFoo assembly, a FooBefore assembly and a FooAfter assembly, and a Test assembly. The idea is that the first release starts out with FooExtensions, IFoo, FooBefore and Test. The test will dynamically load assembly FooBefore and dependent assemblies and create a Foo. It will then call GetMessage and should write to the console “message”. For the second release we only replace FooBefore with FooAfter and run the test again. Then what happens?
#region Assembly FooExtensions
public static class FooExtensions
{
public static string GetMessage(this IFoo foo)
{
return foo.Message;
}
}
#endregion
#region Assembly IFoo
public interface IFoo
{
string Message { get; }
}
#endregion
#region Assembly Foo before update
namespace FooBefore
{
public class Foo : IFoo
{
public string Message
{
get { return "message"; }
}
}
}
#endregion
#region Assembly Foo after update
namespace FooAfter
{
public class Foo : IFoo
{
public string GetMessage() { return "bar"; }
public string Message
{
get { return "message"; }
}
}
}
#endregion
#region Assembly Test
public class Class1
{
public void T()
{
// if extension method is implemented in new version of deriving assembly and
// just that assembly is switched but not dependent assemblies, what happens?
// before update: extension method, as we know it
Console.WriteLine((Activator.CreateInstance("Foo.DLL", "Foo").Unwrap() as IFoo).GetMessage());
// after update: class instance method, but do we know?
Console.WriteLine((Activator.CreateInstance("Foo.DLL", "Foo").Unwrap() as IFoo).GetMessage());
}
}
#endregion
Extension methods are just syntactic sugar for regular static methods, so they will work as before until you recompile the dependent assembly, at which point the compiler will find the new instance method and generate a call to it instead.