Caliburn.Micro
Caliburn.Micro copied to clipboard
Message.Attach picks wrong method because of similar name
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?
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 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")?
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.
@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
.
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.
Can you expand on that, it's nothing something I've used before. But platform availability would certainly be a concern.
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.
Thanks for that, will look it over, may be a bit of sledgehammer to crack a nut, but a definite possibility.
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.