7 ms·
> I liked some of the generics handling better, it can be less verbose it seems. It pays off in spades in a lot of situations, but the biggest I've noticed is
by edgyswingset 12y ago
> I liked some of the generics handling better, it can be less verbose it seems.
It pays off in spades in a lot of situations, but the biggest I've noticed is Android development. Hitting a network from a button press in Xamarin is as simple as:
button.OnClick += async
{
var data = HitTheNetworkForSomeData();
// Note that since this is still async,
// you may want to set a global or have a
// different approach to handling data than
// "standard" Android development.
DoSomethingWithTheData(data);
}
In native Android, it usually looked like this:
button.SetOnClickListener(new OnClickListener() {
new HitTheNetworkTask(this, this).execute()
});
@Override
public void onNetworkTaskDataRecieved(String data) {
doSomething(data);
}
public class HitTheNetworkTask extends AsyncTask<Void, Void, String> {
Context mContext;
NetworkDataTaskCallbacks mCallbacks;
public HitTheNetworkTask(Context context, NetworkDataTaskCallbacks callbacks) {
mContext = context;
mCallBacks = callbacks;
}
@Override
public String doInBackGround(Void... voids){ // I'm not pulling your leg here
return doTheNetworkTask();
}
@Override
public void onPostExecute(String data) {
callbacks.onNetworkTaskDataRecieved(data);
}
}
It's downright frustrating having to use Java once you're used to C# and .NET.
- bad_user 12y agoYou don't need to use Java for Android or for the JVM, you can just use Scala. See Scaloid [1] for setting up Scala for Android and Scala Async [2] to get that nice "async" syntax you've mentioned. [1] https://github.com/pocorall/scaloid https://github.com/pocorall/scaloid [2] https://github.com/scala/async https://github.com/scala/async
- _random_ 12y agoSwitching to Scala would mean learning all the Scala baggage (which has good intentions - granted). C# is much more accessible, while still being elegant - hence the ever-rising popularity.
- bad_user 12y agoI'm a Scala developer, I love Scala (which is why I keep mentioning it) and would be interested to know what baggage you're referring to. For me Scala is more accessible and elegant than both C# and F# and in my opinion has less baggage.
- Retra 12y agoYes, the problem can be solved by using a different language. I'm pretty sure that was the point.
- bad_user 12y agoIt's choosing a different language, versus choosing a different VM, different libraries, a whole different ecosystem, plus it happens to be quite expensive. The JVM is not home only to Java. One PITA for me is that whenever talks about various technologies happen on HN, I tend to comment on disadvantages, because it's the disadvantages that dictate the best use cases for that particular technology. But whenever I do that for .NET / C#, there's like a circle of jerks on HN that down-vote everything that sounds bad about .NET. That's fine, I had some hopes for Microsoft's .NET, now that it is finally being open-sourced and made multi platform, but when choosing a language, you're also choosing the ecosystem around it and this instance, amongst other interactions I've had, confirms that .NET is not for me and probably never will be. Cheers,
- Retra 12y agoI just don't see the relevance of your comment. Nobody had indicated any need to use JVM, as far as I'm aware. So you seemed to be addressing "what's the best language for JVM" rather than "what's the best way to solve this problem." This just isn't a JVM vs .NET competition. If Prolog were the best answer, you could port it to JVM or .NET to your heart's content.
- avens19 12y agoThis. The amount of new Thread(new Runnable(){...}).start() I have in my Android code is awful. And then inside the Thread you have to use runOnUiThread() to change UI stuff. Given how common it is for an app to hit the network, this should be much much easier. Looking at your example it might be slightly easier but it also isn't inlineable. C# solves both of these problems
- ghuntley 12y agoHah; check out RX & http://reactiveui.net/ http://reactiveui.net/ which is the framework behind GitHub for Windows. You will never have to worry about which thread your running on ever again. Doesn't just support WPF - it also works on Windows Phone, iPhone, Mac OSX & Android: public SearchViewModel(ISearchService searchService = null) : ReactiveObject, IRoutableViewHost { SearchService = searchService ?? Locator.Current.GetService<ISearchService>(); // Here we're describing here, in a *declarative way*, the conditions in // which the Search command is enabled. Now our Command IsEnabled is // perfectly efficient, because we're only updating the UI in the scenario // when it should change. var canSearch = this.WhenAny(x => x.SearchQuery, x => !String.IsNullOrWhiteSpace(x.Value)); // ReactiveCommand has built-in support for background operations and // guarantees that this block will only run exactly once at a time, and // that the CanExecute will auto-disable and that property IsExecuting will // be set according whilst it is running. Search = ReactiveCommand.CreateAsyncTask(canSearch, async _ => { return await searchService.Search(this.SearchQuery); }); // ReactiveCommands are themselves IObservables, whose value are the results // from the async method, guaranteed to arrive on the UI thread. We're going // to take the list of search results that the background operation loaded, // and them into our SearchResults. Search.Subscribe(results => { SearchResults.Clear(); SearchResults.AddRange(results); }); // ThrownExceptions is any exception thrown from the CreateAsyncTask piped // to this Observable. Subscribing to this allows you to handle errors on // the UI thread. Search.ThrownExceptions .Subscribe(ex => { UserError.Throw("Potential Network Connectivity Error", ex); }); // Whenever the Search query changes, we're going to wait for one second // of "dead airtime", then automatically invoke the subscribe command. this.WhenAnyValue(x => x.SearchQuery) .Throttle(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler) .InvokeCommand(this, x => x.Search); }
- benjiweber 12y agoIt's a shame Android is still stuck on Java pre-8, as your Java example could be nearly as consise as the c# with Java 8.
- edgyswingset 12y agoIn this particular case, yes. Another issue that comes up is when you've got fairly type-heavy code. C# having real generics just makes things much simpler than in Java.
- benjiweber 12y agoYes c# generics are often a lot less painful, due to lack of type erasure, and support for variable number of type parameters etc. Having said that, more is possible with Java than many people realise. You can read statically available generic type params at runtime (field declarations, supertype tokens etc) . There are also workarounds for most of the erasure problems like methods that vary by generic type parameter only. Java has some nice things itself too. Structural typing of single method interfaces/lambdas makes numerous things much easier. Default methods on interfaces let you do trait-like things nicer than with extension methods. Static imports reduce verbosity. More powerful enums etc. c# approach to type inference seems to be to infer the left hand side of expressions with "var". Java infers types on the right hand side with the diamond operator, method type parameter inference, lambda to interface type inference. The Java approach makes code using fluent chained invocations less verbose, while the c# approach reduces the verbosity of assigning to lots of intermediate variables.
- usea 12y agoC# also infers method type parameters, and will implicitly convert a lambda to a matching interface. Fluent code in C# is also very clean. They're great features in both languages.
- benjiweber 12y agoYou're right, c# does to some extent. On balance I do agree with you, and prefer the set of c# features. Just to clarify - I was thinking of things like this class Example { public static void Main() { Predicate<String> foo = Foo<String>(s => s.Contains("foo")); } static Predicate<T> Foo<T>(Predicate<T> p) { return p; } } I can't replace Foo<String> with just Foo on the right hand side on the 3rd line. I could, however, replace the left hand side with just "var". (n.b. I am using mono, with langver=5. It's possible this is improved in a newer version) Java will infer the RHS class Example { public static void main(String... args) { Predicate<String> foo = foo(s -> s.contains("foo")); } static <T> Predicate<T> foo(Predicate<T> p) { return p; } } The structural typing of lambdas in c# I believe works with delegates? I at least don't know how I'd do the following in c# (I suspect I'd have to define an override of the implicit type conversion operator from a delegate type to a class, or define an extension method called hello on a suitable type) public class Example { interface MyPredicate<T> { boolean test(T t); default void hello() { System.out.println("Hello"); } } public static void main(String... args) { MyPredicate<String> foo = s -> s.contains("foo"); foo.hello(); } } The structural typing here is really powerful, e.g. for working around things like type erasure ;) http://benjiweber.co.uk/blog/2015/02/20/work-around-java-same-erasure-errors-with-lambdas/ http://benjiweber.co.uk/blog/2015/02/20/work-around-java-sam... or more consise builder pattern http://benjiweber.co.uk/blog/2014/11/02/builder-pattern-with-java-8-lambdas/ http://benjiweber.co.uk/blog/2014/11/02/builder-pattern-with...
- taspeotis 12y agoUsing `async` doesn't achieve anything if you're not `await`ing something. `HitTheNetworkForSomeData()` should probably be `await HitTheNetworkForSomeDataAsync()`.
- ghuntley 12y agoCheck out https://github.com/paulcbetts/refit https://github.com/paulcbetts/refit && https://github.com/akavache/Akavache https://github.com/akavache/Akavache && https://github.com/michael-wolfenden/Polly https://github.com/michael-wolfenden/Polly Then check out http://arteksoftware.com/resilient-network-services-with-xamarin/ http://arteksoftware.com/resilient-network-services-with-xam... for the pattern/inspiration how to glue them together to obtain a x-platform resilient, performant and data caching network stack. Write once, enjoy on every platform.