Caliburn.Micro icon indicating copy to clipboard operation
Caliburn.Micro copied to clipboard

Message.Attach picks wrong method because of similar name

Open taori opened this issue 8 years ago • 9 comments

Hello.

I've experienced an issue with this commit: https://github.com/taori/SE-Calculator/commit/9a168ba34b9b422626f054a838ae69a0fa3df1e5

The error i'm running into is with NewShipViewModel.cs basically i have 2 methods with the same name where only the parameter type is different. However it will only enter the method with Delete(Thruster item) if i click on both types. For an energy source it too will enter the method with a thruster, but pass a null as parameter.

I suppose a little fix is required for caliburn to pick the correct method here?

taori avatar Apr 10 '16 01:04 taori

Yup, at the moment it's only looking at count of the parameters and not their types.

It should be possible to do type examination.

nigel-sampson avatar Apr 14 '16 00:04 nigel-sampson

@nigel this would be a significant change from Caliburn's original explicit goal of keeping the Message.Attach functionality extremely limited.

  • would the new implementation handle derived types?
  • interface parameters that are given concrete objects e.g MyMethod(ICollection list) ?
  • generics?
  • generics w/ variance ("in" and "out")?

StephenWard avatar Jun 28 '16 05:06 StephenWard

The functionality would still be limited. Making it pick the correct method in an overload scenario would be a minor extension to prevent unexpected bugs.

taori avatar Jun 28 '16 10:06 taori

@StephenWard I don't think it's a major expansion, we won't be adding more capabilities to Message.Attach, just a better resolver for which method to call when there are overloads.

Thinking over this some more I believe this could be a breaking change if people are depending on the current behavior.

In terms of the scenarios listed above staying away from generics is probably best but the others can be resolved by checking IsAssignableFrom.

nigel-sampson avatar Jun 28 '16 20:06 nigel-sampson

Why not use C# binder from Microsoft.CSharp.dll? It'll choose an override just like C# does. Not sure about its availability on all platforms though.

Athari avatar Jul 27 '16 01:07 Athari

Can you expand on that, it's nothing something I've used before. But platform availability would certainly be a concern.

nigel-sampson avatar Jul 27 '16 02:07 nigel-sampson

DLR is used by C# compiler to implement dynamic keyword. Binder isn't well-documented, but it's mostly about creating weird CallSites like CallSite<Func<CallSite, Type, T1, T2, TObject>> and passing results from Binder's methods to them.

See Dynamitey for sample code, it includes all possible operations. It adds an extra caching level and includes workarounds for bugs (with static methods, iirc), so the code may look more complex than actually needed. Here's a very simplified code I use in a similar scenario for user-provided converters. JSON.NET uses it too, though only for getters and setters and with an additional layer of reflection over it. Considering availability of JSON.NET on many platforms, I think you can rely on its #ifs to see where it's available.

Athari avatar Jul 27 '16 07:07 Athari

Thanks for that, will look it over, may be a bit of sledgehammer to crack a nut, but a definite possibility.

nigel-sampson avatar Jul 27 '16 09:07 nigel-sampson

Considering DLR is built-in and exactly matches behavior of C#, I don't think it qualifies as a sledgehammer. I'd say using anything else would be reinventing the wheel.

Athari avatar Jul 27 '16 11:07 Athari