Proposal: Support Override C# Methods on Instantiation like in Java #2629
Replies: 19 comments
-
First: perhaps change the title to something like "Support Java-style anonymous classes", since that describes what you're actually trying to achieve? The current title is confusing. From your description I can understand needing to write lots of single-use classes, but why are you writing single-use interfaces? Your description doesn't explain that. Anyway, this looks like a duplicate of #2517? |
Beta Was this translation helpful? Give feedback.
-
Partially, I agree, but I'd rather focus on a specific point that a collection of options to emulate from Java. Also, there are two additional points in my proposal:
|
Beta Was this translation helpful? Give feedback.
-
You still haven't provided any details of this in your description. It definitely does not instantiate
Still looks like a duplicate, and the other issue has more discussion as well as some decent proposals. |
Beta Was this translation helpful? Give feedback.
-
Also related #738 and #1542. Unfortunately this is very unlikely to happen, see: dotnet/roslyn#13 (comment) |
Beta Was this translation helpful? Give feedback.
-
What's interesting was that there was a second conversation around the possibility of local classes being added to the C# language where it was mentioned that using local classes is more common than using anonymous classes in Java, which is certainly the exact opposite of my experience. I can probably count the times I've seen local classes used or suggested for callback interfaces on one hand, whereas anonymous classes are suggested by nearly every project that exposes interfaces for use as callbacks. With Java now supporting lambdas effectively as implementations of interfaces this is even more true. If the team were to consider implementing local classes I'd suggest their effort would be significantly better spent on implementing anonymous classes instead. |
Beta Was this translation helpful? Give feedback.
-
To be honest, I'd be in favour of the Java interop layer supporting transparently converting functional interfaces (interfaces with a single abstract method) into delegates - that would mirror what Java does now, and be very natural for C# users. |
Beta Was this translation helpful? Give feedback.
-
How would that work given the possibility of classes that would actually implement that interface as an interface? They can be used in Java as both, and it's not that uncommon to see that happen. There's nothing special about a "functional interface" except for the requirement that it be an interface with a single required method. |
Beta Was this translation helpful? Give feedback.
-
@HaloFour Any method which accepts a functional interface would be given an additional overload which accepts a delegate with the same signature as the functional interface's single method. Nothing to stop you from implementing the interface if you want, but you've got the option of just using a delegate instead if you want, which I think would cut out most of the boilerplate. Java uses lambdas like this anyway: any method which accepts a functional interface can also accept a lambda. Xamarin.ios does something not too dissimilar for e.g. |
Beta Was this translation helpful? Give feedback.
-
Hi, First of all, sorry for sticking my nose into this discussion, I'm just a random passer by interested in C# lang in general. But I haven't ever worked with Xamarin and Android specifically. I'm wondering if code similar to the following snippet can help alleviate the problem that the proposal is addressing? // We can define a "universal" listener,
// it can probably be though of in terms of the adapter pattern.
public class OnClickListener : Java.Lang.Object, IOnClickListener {
private readonly Action<View> _handler;
public OnClickListener(Action<View> handler) { _handler = handler; }
public void OnClick(View v) => _handler(v)
}
// ... Elsewhere in your code ...
var button = new Button();
button.SetOnClickListener(new OnClickListener(handler: v => Console.WriteLine("Hello from an anonymous click handler")));
var button1 = new Button();
void Handler1(View v) { Console.WriteLine($"Hello from {nameof(Handler1)}"); }
button1.SetOnClickListener(new OnClickListener(Handler1)); You'll have to implement an adapter for each IOn*Listener interface, of course. But only once. @FANMixco, I'd be happy to hear your thoughts on the approach described above. |
Beta Was this translation helpful? Give feedback.
-
Hi @mykolav , the problem is that your solution is what we currently have. Think in this way, imagine you're going to create 5, 10 or more of those temp classes per project (almost impossible to work without them), I have some projects in Xamarin with 10, 15 or more of those temp classes that I use them only once, this situation adds complexity, additional effort, and makes it harder to understand and read by someone else because all those temp classes cannot be reused anywhere else, most of the time. Also, this situation effects when you're binding libraries, what is binding a library you might ask? You can use Visual Studio to translate libraries from Java/Kotlin to .NET and from time to time there are very random bugs because VS needs to create these temp classes that can conflict with another name, variable, class, etc. This can happen for multiple reasons, one of them can be: The programmer of the original library didn't follow proper Java/Kotlin standards. I have met even some libraries that share the same names with variables, classes, fake interfaces as annotations (there is no real equivalent in C#, "Attributes") that literally half of the library can be skipped and then is not going to work. In this moment, you have to face five uncomfortable choices:
I stick to my point that this is something worthy to be considered as a part of C#9, it even benefits the Microsoft ecosystem and minimizes many of these potential issues, improving Xamarin as a viable solution in the multi-platform environment. |
Beta Was this translation helpful? Give feedback.
-
@FANMixco, thank you for the detailed response. |
Beta Was this translation helpful? Give feedback.
-
button.SetOnClickListener(new View.IOnClickListener() {
public void OnClick(View v) {
// Perform action on click
}
}); i see at least one issue, it's good that you implement IOnClickListener itself, but who will implement parent interfaces? IJavaObject for example.(also IIRC there is constructor requirements) looks like, for exactly that task, it's better to upgrade Xamarin.Android binding generator to allow it map listener=>event as C# uses(at least reduce missed cases, or may be even allow to give it tips via tranforms files). feature itself is usefull, but IMO, not for that task. |
Beta Was this translation helpful? Give feedback.
-
I provided a detail explanation and I don't think the binder would be a long-term solution since you might have more exceptions that you cannot control and you will need to constantly add them and think in the next one like any odd Java practice that can impact your work. |
Beta Was this translation helpful? Give feedback.
-
As you may have gathered based on the lack of discussion, there has been no movement on this. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Override C# Methods on Instantiation
Summary
To have the ability to create anonymous subclasses that can override it's current implementation avoiding to add unnecessary classes or interfaces with an uncommon use case to your apps.
Inspiration of the topic:
Override Java Methods on Instantiation by Daniel Watrous.
Motivation
I've been building multiple apps with Xamarin.Android and one of the greatest and constant challenges that I face is: When I migrate controls or functions from Java it becomes tricky because each time I need to write new classes or interfaces that are used once, adding complexity and an uncommon codes to my applications.
A good example could be seen in my newest library:
https://github.com/FANMixco/Xamarin-SearchBar
I translated this control:
https://github.com/mancj/MaterialSearchBar
During the translation I faced multiple challenges and I needed to add several extra classes or interfaces just for single cases. This is a regular practice anytime you build a new Xamarin.Android app.
Detailed design
This is a simple example:
Drawbacks
I cannot visualize a reason of why it shouldn't be taken into consideration besides, it could make a bit complex to read the code, but it could expand the current Binder from Xamarin and improve the possibilities to the team.
Alternatives
Current situation:
What other designs have been considered? What is the impact of not doing this?
Unresolved questions
No one.
Design meetings
I haven't had.
Beta Was this translation helpful? Give feedback.
All reactions