I am setting up a testing component and trying to keep it generic. I want to use a generic Visitor class, but not sure about using descendant classes.
Example:
public interface Interface_Test_Case
{
void execute();
void accept(Interface_Test_Visitor v);
}
public interface Interface_Test_Visitor
{
void visit(Interface_Test_Case tc);
}
public interface Interface_Read_Test_Case
: Interface_Test_Case
{
uint read_value();
}
public class USB_Read_Test
: Interface_Read_Test_Case
{
void execute()
{ Console.WriteLine("Executing USB Read Test Case."); }
void accept(Interface_Test_Visitor v)
{ Console.WriteLine("Accepting visitor."); }
uint read_value()
{
Console.WriteLine("Reading value from USB");
return 0;
}
}
public class USB_Read_Visitor
: Interface_Test_Visitor
{
void visit(Interface_Test_Case tc)
{ Console.WriteLine("Not supported Test Case."); }
void visit(Interface_Read_Test_Case rtc)
{ Console.WriteLine("Not supported Read Test Case."); }
void visit(USB_Read_Test urt)
{ Console.WriteLine("Yay, visiting USB Read Test case."); }
}
// Code fragment
USB_Read_Test test_case;
USB_Read_Visitor visitor;
test_case.accept(visitor);
What are the rules the C# compiler uses to determine which of the methods in USB_Read_Visitor will be executed by the code fragment?
I'm trying to factor out dependencies of my testing component. Unfortunately, my current Visitor class contains visit methods for classes not related to the testing component. Am I trying to achieve the impossible?
Since your accept() method doesn't actually call any of the visit() methods, none. :)
However if you invoked it as:
void accept(Interface_Test_Visitor v)
{
Console.WriteLine("Accepting visitor.");
v.Visit(this); // lets invoke it this time
}
the compiler will see that this is first as an instance of USB_Read_Test, then Interface_Read_Test_Case, then Interface_Test_Case. It will choose the most direct overload first (or one where implicit conversions can be used) then go down the inheritance chain until it finds a suitable type that fits an overload. So in this case, it will call visit(USB_Read_Test). You can override this behavior by casting:
v.Visit((Interface_Read_Test_Case)this); // argument is an instance of Interface_Read_Test_Case
v.Visit((Interface_Test_Case)this); // argument is an instance of Interface_Test_Case
If however your class implements multiple interfaces, where each interface has an overload but there is none for the class, you will get ambiguity errors which you will have to resolve.
e.g.,
interface IX { }
interface IY { }
class Class : IX, IY { }
void Call(IX _) { }
void Call(IY _) { }
// no Call(Class _) method
var c = new Class();
Call(c); // error: ambiguous call
Call((IX)c); // not ambiguous
For more information, see Method resolution order and slightly related C#: Passing null to overloaded method - which method is called?.
Instead of defining an entire interface and associated implementations for Visiting, define a Visit method that accepts an Action (or Predicate, or Func depending on what you want the Visitor to do).
class TestCase
{
public void Visit(Action<T> action, T val)
{
action(val);
}
}
var tc = new TestCase();
uint some_val = 3;
tc.Visit((Action) (val) => Console.WriteLine("Val " + val));
Though I'm not entirely clear on what you're trying to do, defining a method that takes a Function can remove the necessity of defining all those interfaces.
As the comment says, accept doesnt invoke any visit methods, so I answer based on what i think you meant...
I would have thought it based on the declared type of the object passed in as a parameter?
USB_Read_Test obj1 = new USB_Read_Test();
Interface_Read_Test_Case obj2 = new USB_Read_Test();
invoking with both as parameters should result in visit(USB_Read_Test urt) for obj1, and visit(Interface_Read_Test_Case rtc) for obj2.
Related
Sorry its a bit vague perhaps but its been bugging me for weeks. I find each project I tackle I end up making what I think is a design mistake and am pretty sure theres a bettwe way.
When defining a class thats serialized from an event source like a sinple json doc definition. Lets call it keys class with various defined integers, bools and strings. i have multiple methods that make use of this and i find that i constantly need to paas this class as an object by means of an overload. So method a calls methods b, method b doesnt need these objects but it calls method c which does... In doing this bad practice im passing these 'keys' objects to method b for the sole purpose of method c accessibility.
Im probably missing one major OOP fundamental :) any guidance or reading would be appreciated as im googled out!!
public class Keys
{
public child Detail { get; set; }
}
public class child
{
public string instance { get; set; }
}
//my main entry point
public void FunctionHandler(Keys input, ILambdaContext context)
{
methodA(input)
}
static void methodA(Keys input)
{
//some-other logic or test that doesn't need Keys object/class if (foo==bar) {proceed=true;}
string foo = methodB(input)
}
static string methodB(Keys input)
{
//here i need Keys do do stuff and I return a string in this example
}
What you do is not necessarily bad or wrong. Remember that in C# what you actually pass are references, not objects proper, so the overhead of parameter passing is really small.
The main downside of long call chains is that the program logic is perhaps more complicated than it needs to be, with the usual maintainability issues.
Sometimes you can use the C# type system to let the compiler or the run time choose the proper function.
The compiler is employed when you overload method() for two different types instead of defining methodA() and methodB(). But they are distinguished by the parameter type, so you need different Key types which may be (but don't have to be) related:
public class KeyA {/*...*/}
public class KeyB {/*...*/}
void method(KeyA kA) { /* do something with kA */ }
void method(KeyB kB) { /* do something with kB */ }
This is of limited benefit; that the functions have the same name is just syntactic sugar which makes it clear that they serve the same purpose.
The other, perhaps more elegant and versatile technique is to create an inheritance hierarchy of Keys which each "know" what a method should do.
You'll need a base class with a virtual method which will be overridden by the inheriting classes. Often the base is an interface just declaring that there is some method(), and the various implementing types implement a method() which suits them. Here is a somewhat lengthy example which uses a virtual Output() method so that we see something on the Console.
It's noteworthy that each Key calls a method of an OutputterI, passing itself to it as a parameter; the outputter class then in turn calls back a method of the calling object. That's called "Double Dispatch" and combines run-time polymorphism with compile-time function overloading. At compile time the object and it's concrete type are not known; in fact, they can be implemented later (e.g. by inventing another Key). But each object knows what to do when its callback function (here: GetData()) is called.
using System;
using System.Collections.Generic;
namespace DoubleDispatch
{
interface KeyI
{ // They actually delegate that to an outputter
void Output();
}
interface OutputterI
{
void Output(KeyA kA);
void Output(KeyExtra kE);
void Output(KeyI k); // whatever this does.
}
class KeyBase: KeyI
{
protected OutputterI o;
public KeyBase(OutputterI oArg) { o = oArg; }
// This will call Output(KeyI))
public virtual void Output() { o.Output(this); }
}
class KeyA : KeyBase
{
public KeyA(OutputterI oArg) : base(oArg) { }
public string GetAData() { return "KeyA Data"; }
// This will compile to call Output(KeyA kA) because
// we pass this which is known here to be of type KeyA
public override void Output() { o.Output(this); }
}
class KeyExtra : KeyBase
{
public string GetEData() { return "KeyB Data"; }
public KeyExtra(OutputterI oArg) : base(oArg) { }
/** Some extra data which needs to be handled during output. */
public string GetExtraInfo() { return "KeyB Extra Data"; }
// This will, as is desired,
// compile to call o.Output(KeyExtra)
public override void Output() { o.Output(this); }
}
class KeyConsolePrinter : OutputterI
{
// Note: No way to print KeyBase.
public void Output(KeyA kA) { Console.WriteLine(kA.GetAData()); }
public void Output(KeyExtra kE)
{
Console.Write(kE.GetEData() + ", ");
Console.WriteLine(kE.GetExtraInfo());
}
// default method for other KeyI
public void Output(KeyI otherKey) { Console.WriteLine("Got an unknown key type"); }
}
// similar for class KeyScreenDisplayer{...} etc.
class DoubleDispatch
{
static void Main(string[] args)
{
KeyConsolePrinter kp = new KeyConsolePrinter();
KeyBase b = new KeyBase(kp);
KeyBase a = new KeyA(kp);
KeyBase e = new KeyExtra(kp);
// Uninteresting, direkt case: We know at compile time
// what each object is and could simply call kp.Output(a) etc.
Console.Write("base:\t\t");
b.Output();
Console.Write("KeyA:\t\t");
a.Output();
Console.Write("KeyExtra:\t");
e.Output();
List<KeyI> list = new List<KeyI>() { b, a, e };
Console.WriteLine("\nb,a,e through KeyI:");
// Interesting case: We would normally not know which
// type each element in the vector has. But each type's specific
// Output() method is called -- and we know it must have
// one because that's part of the interface signature.
// Inside each type's Output() method in turn, the correct
// OutputterI::Output() for the given real type was
// chosen at compile time dpending on the type of the respective
// "this"" argument.
foreach (var k in list) { k.Output(); }
}
}
}
Sample output:
base: Got an unknown key type
KeyA: KeyA Data
KeyExtra: KeyB Data, KeyB Extra Data
b,a,e through KeyI:
Got an unknown key type
KeyA Data
KeyB Data, KeyB Extra Data
I have an Address class:
public class Address
{
//Some stuff
}
and there's a corresponding *Wrapper class to enforce certain rules on how to
use the Address class:
public class AddressWrapper : IWrapped<Address>
{
private Address _wrapped;
public Address GetWrapped()
{
return _wrapped;
}
//And some more
}
where IWrapped is defined as:
public interface IWrapped<T>
{
T GetWrapped();
}
I have the following generic class for saving these entities (there are other
entities that follow this pattern of Entity and EntityWrapper):
public class GenericRepository
{
private GenericRepository() { }
public static void Add<T>(IWrapped<T> entity)
{
//Do something
}
public static void AddList<T>(IList<IWrapped<T>> entities)
{
//Do something
}
}
and I have this test code:
[Test]
public void UseGenericRepository()
{
AddressWrapper addrW = new AddressWrapper();
addrW.AddrLine1 = "x";
addrW.AddrLine2 = "y";
addrW.AddrLine3 = "z";
addrW.City = "Starling City";
//This works as expected
GenericRepository.Add<Address>(addrW);
IList<AddressWrapper> addrList = new List<AddressWrapper>();
//Fill up the addrList
//This gives error: best overloaded method match has some invalid
//arguments
GenericRepository.AddList<Address>(addrList);
}
AddressWrapped is of type IWrapped<Address> (i.e., it implements it) and
Address is the type parameter being given to the AddList method, so the
types should line up. I know that this is due to my limited knowledge of C#
generics (familiar with Java generics), but can't figure out what's wrong here
--- it should work.
This probably doesn't make any difference, but here's my config:
NHibernate 4.x
.NET Framework (4.5)
This is because of the missing type variance of IList<T>. (IList<int> is not an IList<object>).
Use IEnumerable<T>, because it is covariant:
public static void AddList<T>(IEnumerable<IWrapped<T>> entities)
{
//Do something
}
Reason: If you get an instance of List<AddressWrapper>, the compiler doesn't know if it is compatible with any possible implementation of IList<IWrapped<T>>. Assume another class that implements IWrapped<T>. It wouldn't be compatible when writing to the List. Even though you don't write to the list in AddList, the compiler only accepts compatible types. IEnumerable<T> cannot be written, so it can be variant.
Not related to the question I suggest to use covariance for your own interface as well:
public interface IWrapped<out T>
to make IWrapped<Thing> compatible with IWrapped<SpecificThing>.
MSDN: https://msdn.microsoft.com/en-us/library/ee207183.aspx
To make this clear by an example. Would would you expect happen if we had two types implement IWrapped<T>?
public class AddressWrapper : IWrapped<Address>
{
private Address _wrapped;
public Address GetWrapped()
{
return _wrapped;
}
//And some more
}
public class OtherWrapper : IWrapped<MailBox>
{
public MailBox GetWrapped()
{
throw new MailBox();
}
}
And we tried to add them to a third list inside AddList<T>:
public static void AddList<T>(IList<IWrapped<T>> entities)
{
internalList = new List<IWrapped<T>>();
list.AddRange(entities); // BOOM.
}
The type system is keeping you from making a mistake. List<T> isn't covariant exactly for that reason.
At the point at which you're trying to call AddList(), for all the compiler knows, that method may add objects of any type that implements IWrapper<Address> (i.e. types that aren't AddressWrapper) to the passed in list.
That would be bad because the list you're trying to pass to the method doesn't want to contain anything other than AddressWrappers.
NB: Please see the answer by #StefanSteinegger, it is especially enlightening.
What worked for me was changing the way I was defining addrList, from:
IList<AddressWrapper> addrList = new List<AddressWrapper>();
to:
IList<IWrapped<Address>> addrList = new List<IWrapped<Address>>();
However, I am also changing the signature of the GenericRepository.AddList<T>(..) method to take an IEnumerable as that also helps indicate that the input is read-only. So:
public static void AddList<T>(IEnumerable<IWrapped<T>> entities)
{
//Do some stuff
}
I have a class implementing a concrete typed version of a generic interface. I have found that if I pass an object in to my function (even though it might be the correct object) at compile time it is still considered an object and thus failing at runtime with the error:
Unable to cast object of type 'TestEventHandler' to type 'IDomainEventHandler '1[System.Object]'.
I am deserializing messages from a bus (which products objects, which should have an associated DomainEventHandler<of_deserialized_type> associated with the message.
In summary, the problem I believe is IDomainEventHandler<T> not casting from `IDomainEventHandler<object>, I would appreciate guidance on how best to solve this issue and still maintain the generic IDomainEventHandler<T> interface even with objects being passed in to Publish().
[TestClass]
public class InternalMessageHandlerTests
{
class TestEvent
{
}
class TestEventHandler : IDomainEventHandler<TestEvent>
{
public void HandleEvent(TestEvent domainEvent)
{
}
}
[TestMethod]
public void Test()
{
TestEvent testEvent = new TestEvent();
object testEventAsObject = testEvent; // compile time type information lost
Publish(testEvent); // this is OK :)
Publish(testEventAsObject); // this fails :(
}
public void Publish<T>(T eventToPublish) where T : class
{
var handlerInstance = new TestEventHandler();
IDomainEventHandler<T> converted = (IDomainEventHandler<T>)handlerInstance;
converted.HandleEvent(eventToPublish);
}
}
You can't convert TestEventHandler to IDomainEventHandler<object> since this is not safe. If it were allowed you could do:
IDomainEventHandler<object> converted = (IDomainEventHandler<object>)new TestEventHandler();
converted.HandleEvent("dsfs");
which is invalid since TestEventHandler requires its argument to HandleEvent to be TestEvent.
You could invoke Publish using reflection:
TestEvent testEvent = new TestEvent();
object testEventAsObject = testEvent;
var publishMethod = this.GetType().GetMethod("Publish").MakeGenericMethod(testEventAsObject.GetType());
publishMethod.Invoke(this, new object[] { testEventAsObject });
In this situation, it is not possible to support a fully-generic interface without reflection. And reflection is a pretty bad idea for such a simple case.
My normal approach for these situations is IDomainEventHandler, then DomainEventHandlerBase<T> : IDomainEventHandler so that inheriting classes get all advantage of generics, but outside interface can accept objects.
Obviously it is not statically safe, but as I said it is not possible to be statically safe here. As soon as you assigned your instance to object testEventAsObject, you made it possible for this variable to contain anything from the compiler point of view (string, int, anything).
For the things like service bus where you have to select the right handler, it would look like this:
public interface IDomainEventHandler {
void HandleEvent(object domainEvent);
bool CanHandleEvent(object domainEvent);
}
public abstract class DomainEventHandlerBase<T> : IDomainEventHandler {
public abstract void HandleEvent(T domainEvent);
public abstract bool CanHandleEvent(T domainEvent);
void IDomainEventHandler.HandleEvent(object domainEvent) {
return HandleEvent((T)domainEvent);
}
bool IDomainEventHandler.CanHandleEvent(object domainEvent) {
return (domainEvent is T) && CanHandleEvent((T)domainEvent);
}
}
I has written that directly (without checking in VS) so mistakes are possible.
After that when you receive a message just select
handlers.First(h => h.CanHandleEvent(domainEvent))
The short version of what I am looking for is this:
I am looking for a mechanism which, given an interface, will dynamically generate a pair of classes for that interface, one multiplexer and one demultiplexer, which will convert calls to/from a general-purpose delegate of the following form: object AnyCall( int method_selector, object[] arguments ). The multiplexer class will accept an AnyCall delegate as a construction-time parameter, and it will implement the interface by delegating every call to the delegate. The demultiplexer class will accept a reference to the interface as a construction-time parameter, and it will implement the delegate by switching on the method selector and invoking the appropriate method of the interface, passing it the parameters that were passed to the delegate.
The long version of what I am looking for is this:
Consider the following interface:
public interface IFooable
{
void Moo( int i );
void Boo( string s, bool b );
}
And consider the following class implementing that interface:
public class FooImplementation: IFooable
{
void IFooable.Moo( int i ) { System.Console.WriteLine( "i: " + i ); }
void IFooable.Boo( string s, bool b ) { System.Console.WriteLine( "s: " + s + ", b: " + b ); }
}
And then consider the following class making use of the above:
public partial class MuxdemTest
{
public static void InvokeFoo( IFooable fooable )
{
fooable.Moo( 42 );
fooable.Boo( "fubar!", true );
}
public static void Run1()
{
IFooable fooable = new FooImplementation();
InvokeFoo( fooable );
}
}
Nothing fancy here.
Now let us suppose that instead of giving InvokeFoo() a direct reference to FooImplementation I would like to embed some functionality inbetween the two that would allow me to do some really useful things with the interface method calls, like, say, count the number of times a call was made to one of the methods of the interface; or convert the calls into messages and deliver them to a FooImplementation that resides on a different thread; or on a different continent; or whatever. And of course this inbetween functionality should be able to work on ANY interface, not just IFooable.
In order to achieve this, we need a way to multiplex calls to methods of an interface into invokations of a single general-purpose delegate, and later demultiplex them from invokations to that delegate into interface method calls. The delegate I am thinking of would have the following form:
public delegate object AnyCall( int method_selector, object[] arguments );
So, here is an implementation of a multiplexer for the IFooable interface:
public class MuxForFooable: IFooable
{
private readonly AnyCall AnyCall;
public MuxForFooable( AnyCall anycall ) { AnyCall = anycall; }
void IFooable.Moo( int i ) { AnyCall( 0, new object[]{ i } ); }
void IFooable.Boo( string s, bool b ) { AnyCall( 1, new object[]{ s, b } ); }
}
And here is an implementation of a demultiplexer for the IFooable interface:
public class DemuxForFooable
{
public readonly IFooable Target;
public DemuxForFooable( IFooable target ) { Target = target; }
public object AnyCall( int method_selector, object[] arguments )
{
switch( method_selector )
{
case 0: Target.Moo( (int)arguments[0] ); break;
case 1: Target.Boo( (string)arguments[0], (bool)arguments[1] ); break;
default: throw new System.InvalidOperationException();
}
return null;
}
}
And here is a piece of code that makes use of the above, achieving exactly the same thing as the Run1() method above, the difference now being that all calls pass through an 'AnyCall' delegate:
public partial class MuxdemTest
{
public static void Run2()
{
IFooable fooable = new FooImplementation();
DemuxForFooable demux = new DemuxForFooable( fooable );
MuxForFooable mux = new MuxForFooable( demux.AnyCall );
InvokeFoo( mux );
}
}
My only problem is that the classes MuxForFooable and DemuxForFooable have been hand-written, while I want them dynamically generated. Consider the following mock methods that would generate them, and a piece of code that would use those methods:
public partial class MuxdemTest
{
public static T CreateMux<T>( AnyCall anycall )
{
if( typeof(T) == typeof(IFooable) )
return (T)(IFooable)new MuxForFooable( anycall );
throw new System.NotImplementedException();
}
public static AnyCall CreateDemux<T>( T target )
{
if( typeof(T) == typeof(IFooable) )
return new DemuxForFooable( (IFooable)target ).AnyCall;
throw new System.NotImplementedException();
}
public static void Run3()
{
IFooable fooable = new FooImplementation();
AnyCall demux = CreateDemux<IFooable>( fooable );
IFooable mux = CreateMux<IFooable>( demux );
InvokeFoo( mux );
}
}
Run3() above has exactly the same effect as Run2() and Run1() further above.
So, has anyone ever written or knows how to write actual implementations for CreateMux() and CreateDemux()?
You may assume that the interfaces will contain only methods and no properties, and that all methods will return void and will not accept any "ref" nor "out" parameters. (Even though I would not mind an implementation that would allow these things.)
There are lots of code samples out there that do things similar to what I want, but I am posting this question in the hope that someone has already done exactly what I want to do, because the subject of dynamic code generation is very tricky.
I am aware that what I want can be accomplished with existing proxy frameworks like CastleProxy, but I do not want to use an entire external framework for such a simple task, nor do I want the runtime overhead incurred by the use of such a framework. I looked at the source code of CastleProxy trying to figure out how to use parts of it to do what I want, but I found it way too convoluted to make any sense out of it.
Edit 1:
Six months later, I implemented a tool which does what I was asking for in this question. I am going to publish a paper about it, but before I do that, I need help with the naming, so I opened another question: Need help with naming (marshaling interface calls)
In the mean time, please feel free to add an answer if you have one.
Edit 2:
I decided to call the tool "intertwine", and the operations "entwine" and "untwine". If you want to read about it, here it is: michael.gr - Intertwine: Normalizing Interface Invocations
In order to achieve this, we need a way to multiplex calls to methods of an interface into invokations of a single general-purpose delegate, and later demultiplex them from invokations to that delegate into interface method calls.
I don't see how this follows from your requirements. I think what you actually want is DynamixProxy, or something similar. With it you can intercept calls to methods, which seems to be exactly what you want. Simple example:
class LoggingIntereceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine(invocation.Method);
invocation.Proceed();
}
}
…
public static void Run1()
{
var generator = new ProxyGenerator();
IFooable fooable = generator.CreateInterfaceProxyWithTarget<IFooable>(
new FooImplementation(), new LoggingIntereceptor());
InvokeFoo(fooable);
}
This gives the following output:
Void Moo(Int32)
i: 42
Void Boo(System.String, Boolean)
s: fubar!, b: True
DynamicProxy generates a type that implements the interface at runtime, so it should be quite fast.
If you don't want to add “an entire framework” to your projects, you don't have to. What you need to run the example above is only one additional assembly: Castle.Core.dll.
I just read oracle.com: Dynamic Proxy Classes and found out that the java runtime environment offers half of what I am looking for. In their own words:
A dynamic proxy class is a class that implements a list of interfaces
specified at runtime such that a method invocation through one of the
interfaces on an instance of the class will be encoded and dispatched
to another object through a uniform interface.
The relevant facility is in the java.lang.reflect package: The Proxy class creates multiplexers, and the InvocationHandler interface plays the role of my AnyCall delegate. Java does not appear to offer any means of creating demultiplexers; why, I do not know.
My guess until now was that a dynamic type just "switches off" type checking during compilation and does something similar to a type cast when a message is invoked on a dynamic instance. Obviously something else is going on.
The attached NUnit test case shows my problem: Using a dynamic type I can use a method only available in the concrete subclass, but I cannot do the same using a cast (results in InvalidCastException). I'd rather do the casting since this gives me full code completion in VS.
Can anyone explain what's happening and/or give me a hint how I could get code completion in my case without having to reimplement the WorkWithAndCreate-method in every concrete subclass?
cheers, Johannes
using System;
using NUnit.Framework;
namespace SlidesCode.TestDataBuilder
{
[TestFixture]
public class MyTest
{
[Test]
public void DynamicWorks()
{
string aString = CreateDynamic(obj => obj.OnlyInConcreteClass());
Assert.AreEqual("a string", aString);
}
private static string CreateDynamic(Action<dynamic> action)
{
return new MyConcreteClass().WorkWithAndCreate(action);
}
[Test]
public void CastingDoesNotWorkButThrowsInvalidCastException()
{
string aString = CreateWithCast(obj => obj.OnlyInConcreteClass());
Assert.AreEqual("a string", aString);
}
private static string CreateWithCast(Action<MyConcreteClass> action)
{
return new MyConcreteClass().WorkWithAndCreate((Action<MyGenericClass<string>>) action);
}
}
internal abstract class MyGenericClass<T>
{
public abstract T Create();
public T WorkWithAndCreate(Action<MyGenericClass<T>> action)
{
action(this);
return this.Create();
}
}
internal class MyConcreteClass : MyGenericClass<string>
{
public override string Create()
{
return "a string";
}
public void OnlyInConcreteClass()
{
}
}
}
Here's the formatted real world example from my comment:
Customer customer = ACustomer(cust =>
{
cust.With(new Id(54321));
cust.With(AnAddress(addr => addr.WithZipCode(22222)));
});
private static Address AnAddress(Action<AddressBuilder> buildingAction)
{
return new AddressBuilder().BuildFrom(buildingAction);
}
private static Customer ACustomer(Action<CustomerBuilder> buildingAction)
{
return new CustomerBuilder().BuildFrom(buildingAction);
}
Some details are missing from it but I hope it makes the purpose clear.
The reason dynamic works is that dynamic does not depend on compile time knowledge of the object types. MyGenericClass<string> does not have the method OnlyInConcreteClass(), but the instance you are passing of course does have the method and dynamic finds this.
By the way, you can make WorkWithAndCreate work like this:
public T WorkWithAndCreate<T1>(Action<T1> action)
where T1 : MyGenericClass<T>
{
action((T1)this);
return this.Create();
}
Then, the call will work too:
private static string CreateWithCast(Action<MyConcreteClass> action)
{
return new MyConcreteClass().WorkWithAndCreate(action);
}
You now don't have to cast it anymore.
And concerning your builder, would the following work?
private static TResult AnInstance<TBuilder, TResult>(Action<TBuilder> buildingAction)
where TBuilder : Builder<TResult>, new()
{
return new TBuilder().BuildFrom(buildingAction);
}
This is an example of how to use dynamic:
http://msdn.microsoft.com/en-us/library/dd264736.aspx
You said:
My guess until now was that a dynamic type just "switches off" type checking during compilation and does something similar to a type cast when a message is invoked on a dynamic instance
Actually, it uses reflections to look up the methods, properties, and fields you invoke by name, at runtime. No casting is done, unless you actually cast the object back to its underlying type.
As for your actual problem, can you give a more concrete example? There may be a better design, but you haven't told us what you're trying to do - just what you're currently doing.
Hazarding a guess, you may want to use a base interface, and make all your functions accept that base interface. Then put the methods you want to call on that interface, and implement them in your concrete types. Usually dynamic is used as a work around when you don't have a base type, or can't modify the base type to add virtual or abstract methods.
If you really want to get this working, as-is, you must write it with a generic type parameter, not a dynamic type parameter. See Pieter's solution for how to do this properly.