1

I've got two objects which (Domain and Data) which in this case have the same property (let's presume Name). I've got an Action<DomItem> which I would like to cast to Action<DataItem>.

public  class DomItem {
    public string Name { get; set; }
}

public class DataItem {
    public string Name { get; set; }
}

public class Program {
    public Program() {
        Action<DomItem> domAction = new Action<DomItem>(x=>x.Name = "Test");
        // Something Casted To Action<DataItem>(x=>x.Name = "Test");
    }
}

Of course this is just a basic example. It's by design that I can NOT use a common interface. I do not care about the DataItem might not be having the same property.

I've been looking into Expressions and several other solutions but I just can't figure out how to create the Cast (or get the "x=>x.Name =..." part from the method).

Any help would be really appreciated!

Daniel
  • 9,491
  • 12
  • 50
  • 66
  • 2
    Why don't just use AutoMapper? – Oleksii Aza Aug 13 '15 at 19:59
  • Please explain how oleksii. – MightyMouseTheSecond Aug 13 '15 at 20:02
  • Christian, It's just an example. I want the DataItem to run the action on itself which I've defined on the DomItem. – MightyMouseTheSecond Aug 13 '15 at 20:11
  • In response to Oleksii: I have the Actions defined based on my DomItem. I need to translate them to Actions based on DataItem. It's not that I want to use Before or After Mapping. I really need to cast the Actions. – MightyMouseTheSecond Aug 13 '15 at 20:14
  • @MightyMouseTheSecond OK I see. You will probably need to use reflection to get the delegates parts and then translate them into your DataItem context. – Christian Aug 13 '15 at 20:16
  • @Christian I've been looking into that but I can't seem to get the cast to work. I'm pretty lost for any solution ;-) – MightyMouseTheSecond Aug 13 '15 at 20:18
  • so you want some kind of duck-typing-variance-cast ... don't do this (it might actually work if you just go `dynamic`) - you basically say good-bye to the type-checker - in the case at hand just implement it by hand - it will even be faster at runtime (yeah it's copy&past - so what?) – Random Dev Aug 13 '15 at 20:40
  • @Carsten you are correct by stating that copy&past is possible. That would be my last resort. But I still would like to know if it's even possible to cast the Action (I've been searching and trying for quite some time now). – MightyMouseTheSecond Aug 13 '15 at 20:45
  • By any chance are you actually have `Expression>` instead of `Action`, it makes the problem a lot easier. – Scott Chamberlain Aug 13 '15 at 20:47
  • 1
    @MightyMouseTheSecond Have a look at [this](http://stackoverflow.com/a/3673216/360674) answer. Should be something what you need. – Christian Aug 13 '15 at 20:53
  • @ScottChamberlain Could you explain how to create an Expression>. At this point I get confused how to create an Expression>. – MightyMouseTheSecond Aug 13 '15 at 21:16
  • `x=>x.Name = "Test"` is a valid `Expression>` too so you could just do `Expression> domAction = x=>x.Name = "Test";`. Expressions are what you normally work with when dealing with EntityFramework or similar. – Scott Chamberlain Aug 13 '15 at 21:17
  • @ScottChamberlain It gives me an exception: An expression tree may not contain an assignment operator. That's why I asked. – MightyMouseTheSecond Aug 13 '15 at 21:31

1 Answers1

2

You can't directly or indirectly cast a Action<DomItem> to an Action<DataItem>, but you could wrap the action with a converter that converts the input from a DataItem to a DomItem and runs the original action on the copy:

public Action<DataItem> Convert(Action<DomItem> action)
{
    return new Action<DataItem>(o => action(Map(o)));
}

public DomItem Map(DataItem dataItem)
{
    return new DomItem{Name = dataItem.Name};
}

The obvious downside is that the action will be applied to a copy of the original object and not the original object itself. Without knowing exactly what the action is I don't know of a way to "cast" the action without a common base type.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • this won't work as the action is not to set the name but I want the DataItem (which goes to EF) to perform a certain SQLQuery (hence the Action). I tried to simplify the question to prevent a huge amount of code. I really need to know how to cast an Action to an Action and not a work-arround. Thank you for your anwser. – MightyMouseTheSecond Aug 13 '15 at 22:13
  • You can't cast an `Action` to an `Action`. Note that the action returned is not setting the name - it's wrapping the _original_ action passing in a new `DomItem` with the properties mapped from the original `DataItem`. – D Stanley Aug 13 '15 at 22:30
  • Thank you for the input @D-stanley. I will try to find another sollution. – MightyMouseTheSecond Aug 14 '15 at 09:29