Recently I got to use some C# on Linux (with Mono framework), and I gotta say it wasn't bad. I didn't do anything with GUI elements, was all back-end server code.
C# wouldn't be my top "go to" language, but I would put it above Java. I liked some of the generics handling better, it can be less verbose it seems.
Monodevelop is not on par with Visual Studio, but it is solid and worked well for me. I usually don't like IDEs, but for a new language/framework and large projects it was very helpful to have it.
Wondering if open sourcing .NET core will breathe a new life into Mono project and maybe it is going to be bigger thing that what we expected -- we'll start seeing more back-end usage of .NET.
F# is nice too, and if anyone stayed away because of having to use Windows, maybe now is a time to take a second look.
> 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.
This. 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
Hah; check out RX & 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);
}
"Not worrying about the thread" is actually a feature of TPL. A SynchronizationContext[1] is stored in thread local storage for UI threads, which can be used to queue calls back to that thread (a .Net 2.0 feature). When you `await` something, TPL takes advantage of the original SynchronizationContext and the callback will be automatically made on the UI thread.
If you implement SynchronizationContext and set it, you can actually have the TPL call back into whatever special threading stuff you want.
It doesn't work for WPF bindings, but for the quick'n'dirty procedural UI code it works great.
In 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.
Yes 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.
C# 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.
You'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();
}
}
Awesome examples, thank you. I apologize if you already know all of this stuff. You seem much more knowledgeable about this than me.
As for type inference, C# will sometimes infer the RHS from the LHS, lambdas are one example. Also sometimes it can figure out the types from a lambda. Here is an example where the type information for inference comes from the literal int zero:
public void Main()
{
var i = 0;
var list = MakeThree(() => i++);
//[0, 1, 2]
}
private IList<T> MakeThree<T>(Func<T> generator)
{
return new List<T>{ generator(), generator(), generator() };
}
C# will infer method type parameters from arguments. In your example, there wasn't a type on the parameter to use as a source of inference. You could write it instead as (contrived example):
Predicate<string> p = s => s.Contains("foo");
var foo = Foo(p);
The type parameter on Foo is inferred, as well as the variable type on the LHS. The only time I write a type on the LHS is when I am assigning a lambda to a variable. And that is not super often. More realistically though, you would be passing a collection or something else that already has a type. For example in LINQ's IEnumerable<T> extension methods, the IEnumerable<T> is the source of the type information as the first parameter to the extension method, so everything is inferred from there. It's extremely rare for me to type a method type parameter. I cannot remember the last time I did. I do write the types for constructors often, though. new List<int>(), new Dictionary<string, Foo>() etc. I guess the tradeoff is that in java you can infer a lambda's type by writing it on the LHS, while in C# you are going to have to get that type from somewhere else. Either write it on the RHS, or it will be written on some other variable or method.
Also I use Func and Action every day, but I basically never use other delegate types.
Your example of structure typing of lambdas looks weird to me. It's the same feeling I get when I see a downcast. I mean no criticism; I suspect this is a Blub reaction in me. I am not used to looking at the left-hand side to figure out the type for the right-hand side. Lambdas will implicitly convert to a Func or Action. A reference to a method with a matching signature will also convert. As a silly example: Select takes a Func<T, U>, and will implicitly convert a method that accepts the same T as its only parameter.
public ShortTons ConvertTons(LongTons t) { ... }
public void Main()
{
var readings = GetReadings();
var exportWeights = readings.Select(x => x.Weight).Select(ConvertTons);
}
In this example, there are elided, inferred type parameters everywhere. The source of the type is in the missing GetReadings method, and the Weight property on the reading type. That's pretty typical.
That builder pattern is pretty cool. In C# you have object initialization syntax, which is similar in being more readable as to which members are getting set. However, that's pretty much incompatible with immutability afaik. It only lets you set public properties with public setters. Normally you would make something immutable by making your setters private, or leaving them off entirely. Public fields (even readonly ones) are strongly discouraged in C#. Either way, that prohibits object initialization.
Thanks for responding, I learned a lot about Java.
Why? I hear this a lot, but I never understood it. I do a lot of work with reflection to achieve things I can't otherwise do (around application extension, dynamic systems for games, etc.).
I mean, attributes are reflection, and they're absolutely invaluable.
Because it's not maintainable in a large code base. You write your code, and move on to something else, someone else comes a long and does a refactor, but they and/or the IDE misses the member names that were in strings. The program crashes on the next deploy because it built just fine.
Reflection is like anything else it can be used properly and it can be abused. I've seen it abused far too many times.
I realize there are times in Java when reflection is unavoidable (Android's animation libraries rely on it), but I consider it to be a feature of C# that, so far, I've never had to use reflection in C#.
How Google handles the whole developer quality experience in Android, Java 8 might eventually be supported by the time we have Java 10, with reifeid generics, modular, value types, JNI replacement, ...
If ever, given their attitude on last year's Google IO.
Using `async` doesn't achieve anything if you're not `await`ing something. `HitTheNetworkForSomeData()` should probably be `await HitTheNetworkForSomeDataAsync()`.
You 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.
It'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.
I 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.
Switching 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.
I used to work in C# (now mostly live in JavaScript land) and I miss things like LINQ a lot. So here's hoping we see wider adoption of C# in the future.
I don't mind C# not using that name because .Where doesn't actually filter the object, it returns an IQueryable, which you can chain further statements onto, then filter.
The LINQ API is modeled after relational algebra (where `Select` acts as projection, and `Where` acts as selection, etc.), which is as good a basis for operations on collections as anything. It is not even clear that other popular names have precedent, let alone especially useful expressive power beyond what normal relational algebras afford.
Besides that, one of the early intents behind LINQ was to allow a language-integrated ORM, so LINQ's choices for names are actually extremely appropriate.
On human-friendliness, filter can read as a physical metaphor, so scores rather well. Just need to remember whether what's caught is kept or discarded.
I think your "executed like" is missing another foreach loop, and the actual function calls (lambdas don't get inlined on the C# compiler, and it's a bit of a crap shoot when counting on the JIT). The end result is the same, but you're eliding a bunch of allocation, branches and method invocations that occur in the actually executed code. Which is the whole point of optimizations for such code, which LINQ lacks.
In fact, how else could "Where" be implemented while keeping lazy semantics?
(Rust, AFAIK, can actually do this, by inlining everything including the lambdas.)
You're right it's missing the actual function calls, but that wasn't the point: the point here was that LINQ avoids building temporary enumerations and iterating over them like JS functions do.
But here's a microbenchmark[1]. It's still not close to non-LINQ code. A factor of 10, with a trivial body, just summing up some numbers. (I didn't used Sum() as it appears to use checked arithmetic.)
As far as the optimizations, the smart combining code (which still has to allocate a combined delegate + lambda object, that'll cost, what 2 objects at like 40 bytes each?)) only happens when Select is followed by Select, or Where by Where. Select after Where gets a new "WhereSelectEnumerableIterator" and so on.
So you're right that it does eliminate some overhead though depending on the order of your Wheres and Selects there may be more "foreach" loops in the comparable code. And it's still not even close to being free like it should be. (Like, say, Haskell can do sometimes.)
That's not the same, though; that's you purposefully combining your query (which you can do in LINQ).
LINQ doesn't just combine Wheres. It tries to optimize your query as much as possible and executes lazily, so you aren't actually doing any work until you try to use the resultset (in a ToList, for example).
I don't know about Underscore, but lo-dash [0] supports lazy execution of a chained query without generating intermediate arrays (see docs [1]). It offers something pretty similar to LINQ queries on collections (except you don't get the benefit of strong typing).
Yes. IQueryable actually implements an expression tree, which means that it may never be executed, at least directly. LINQ to Entities (Entity Framework) actually evaluates the expression tree to build SQL statements, then runs those and returns the results (after coercion back to the mapped POCO object).
Right. Actually Linq to SQL did the same thing, but a big philosophical difference is Entity will reject stuff that it can't resolve from the database instead of just letting you do whatever (which may involve multiple queries).
Lazy.js (http://danieltao.com/lazy.js/) is probably a closer equivalent. Linq statements are evaluated lazily, generally without needing to create intermediate arrays.
Just out of curiosity, what is your go-to language?
C# is probably my favorite general purpose language so far, although I really prefer Golang's goroutines/channels over C#'s async model. Curious to hear other perspectives!
Task<T>/async is a slightly different beast, effectively its a goroutine+channel which can only return 1 value or throw an exception.
A better alternative to channels is Rx (Reactive Extensions) which gives you IObservable<T>. It's very simple and powerful. Observables can be composed using Linq, and they're monadic (if that matters). I like the first class notion that something can fail or be completed (go has close(), which lets you complete a channel, but there is no notion of errors unless you slap a tuple in there).
Rx is available on many platforms (incl JVM, JS).
Rx.NET does not yet support back pressure (Rx 3.0 will, whenever Microsoft release that, maybe at //build). There's an alternative library from Microsoft called Dataflow, though, and Dataflow does support backpressure as well as a lot of other great features. Dataflow is underused, but its great. Rx & dataflow interoperate very easily (.ToObservable() etc)
There are a bunch of videos from Netflix on their use of Rx, which are a good watch if you're interested.
Edit:
Channels in Go don't compose: I can't easily take one channel, mutate the values as they arrive, and create another channel from the mutated values.
With Rx, that's just `var uppers = keyPresses.Select(key => key.ToUpper())` and now I've got a new stream of data. If keyPresses completes, so does uppers. If it fails, that failure is propagated through uppers. This isn't easy in Go.
goroutines don't have any reasonable kind of monitoring. I can't say "this routine has completed/failed", I have to implement that notion every single time using a WaitGroup or something, and that only handles completion, not failure.
I'm not saying C# is perfect and that go's channels/goroutines don't have any merit, just that there are some things I wish I could do more easily using them.
Playing along with the exercise (by temporarily ignoring everything else that indicates the Java is far more popular than C#) and just using your job site approach, it seems that the UK is pretty different from the US.
Looking at US job search sites, Java has about 2 times as many results as C# in the US overall, and 3-6 times as many in SF and New York. Java even has almost twice as many results in Seattle.
F# is a pure joy to work with. If your interested in learning it, getting involved or just staying up to date with the news then subscribe to this blog @ https://sergeytihon.wordpress.com/tag/newsf-weekly/
I'd say Python is more like C# and Java than it is like F#. If you've never used F# (or Haskell, or something else like them) you're in for a surprise.
Apart from that: I'm really curious and sort of excited to see what the next years will bring in terms of development using .Net in general and C#/F# specifically, on multiple platforms.
What I still don't understand in this picture is the what does the future look like in terms of the .NET framework.
.NET Core sounds great, and its great that they are unifying the implementation, not just the API, for many of the "app models". But, its unclear to me if there's the intention for .NET Core to fully succeed .NET Framework at some point in the future. Or, rather, will some of the app models we see on top of the Framework right now (WinForms, WPF apps) be built with .NET Core in some future version?
I think the reason why the future isn't spelt out is because they don't know (or haven't decided). The last 12 months have been massive steps for Microsoft (open source, multi platform). I would expect they would wait and see how their customers & community react.
Also Azure is a massive component to all of this (they make money of Azure, they don't make a massive amount of cash from someone using .Net).
Microsoft have a long history of keeping old versions alive (unlike say Apple). Eg Internet Explorer, Windows XP, Office, Win Forms vs MVC
I'm sure .Net core will take over one day. In the same way .Net 4.5 overtook .Net 2 / 1.1 etc.
I'm wondering the exact same thing. What is the relationship between the two? How easy is it to bridge them or is that not possible? I mean suppose I want to write some typical backend utility code like extensions for collections etc: can the same code for .NET framework be used for .NET core? Eventually with some #ifdefs?
- Groovy is nice and still very similar to Java(no learning curve)when you want syntactic sugar like LINQ or JDBC SQL without all the boilerplate code.
- IntelliJ Idea is similar to Visual Studio + Resharper.
But the biggest reason to start using Java is its extremely mature and rich ecosystem!
I'm currently doing software development on Windows with C#.Net and Visual Studio without ReSharper and I really miss Linux, Java and IntelliJ Idea :(
The Clojure language is far more mature on the JVM than on .NET. Clojure is useful for scripting Java classes, and you can use its macros to create new syntax if other JVM scripting languages (e.g. Beanshell, Xtend, JRuby, Jython) don't have pre-existing syntax to meet your needs.
Scala has almost every feature of C#, while the inverse is not true. I miss visual studio a bit when doing scala, but never the language. When I'm doing .NET work, I sorely miss scala.
Happy to have a in depth article like this; bookmarked for later today hopefully.
My background is in the LAMP stack but now work in an enterprise environment where everything is .NET (though much older .NET than this article is talking about).
I want to throw myself into it but right when I started there was all this new talk about vNext and changes to .NET and all this other excited, though daunting, discussion around it.
.NET Native ... It would be great to have it for back-end also as opposed to only front-end. I'd take that 60% startup increase in IIS also, the first request is always slow...
> I'd take that 60% startup increase in IIS also, the first request is always slow...
But startup cost is less relevant in a server scenario. In a server you startup once per ~1B requests or more. In a front-end app, it might run 10 requests and then stop.
Agreed. But we do have API for internal jobs that are only used a few times a week. Then there is also the other 15%-20% memory reduction discussed in the article that I'd like to have back.
I learned to code with python, php, and javascript mostly. I could never get into visual studio / .net, it always felt so long winded compared to python.
I like that now there is a viable alternative to Java across various platforms. Java the language is alright but the ecosystem is something else entirely.
It's not a reimplementation but a gradual publish of existing code, upgraded to meet the required standards (some of it was not written with being open in mind).
WPF will not be available on non-Windows platforms. That has always been the case and will remain so - it has a far to deep integration with the OS for it to ever be platform independent and a reimplementation would be an absolutely ginormous effort.
And on a tangent, I guess the WPF thing was expected. But! I also thought WPF is mostly a re-implementation of all the windows widgets on top of a framebuffer - it doesn't use native win32 buttons, dropdowns, text rendering, etc etc...?
I don't think it's written from scratch. Why would it be? WPF and Windows Forms have some Windows specific stuff that would be irrelevant in a cross-platform version.
I remember looking at the corefx github project just after the announcement, and it was very sparse with just a few commits and classes; it looked a lot like a brand new project written from scratch.
This wording also makes it sound like ".net core" is a re-boot, scorched earth reimplementation which will take some time to reach the levels of the original .net:
>.NET Framework 4.6
>The .NET Framework is still the platform of choice for building rich desktop applications and .NET Core doesn’t change that.
>For Visual Studio 2015 our goal is to make sure that .NET Core is a pure subset of the .NET Framework. In other words, there wouldn’t be any feature gaps. After Visual Studio 2015 is released our expectation is that .NET Core will version faster than the .NET Framework. This means that there will be points in time where a feature will only be available on the .NET Core based platforms.
In fact, a quote from [1] clearly states that it contains "largely the same code ... refactored":
".NET Core also includes the base class libraries. These libraries are largely the same code as the .NET Framework class libraries, but have been factored (removal of dependencies) to enable us to ship a smaller set of libraries."
I think the state of the Windows Store shows that approximately nobody took that seriously.
Unfortunately there are a few libraries I use at work that were released around the whole Windows RT/JS debacle, so their documentation takes a little more figuring, and is frequently incorrect, due to only having code samples in these dead/orphaned variants.
I think part of it is that MS tied WinRT to full screen-only apps, a mistake they're fixing in Windows 10. Some of the features of the WinRT API look neat.
C# wouldn't be my top "go to" language, but I would put it above Java. I liked some of the generics handling better, it can be less verbose it seems.
Monodevelop is not on par with Visual Studio, but it is solid and worked well for me. I usually don't like IDEs, but for a new language/framework and large projects it was very helpful to have it.
Wondering if open sourcing .NET core will breathe a new life into Mono project and maybe it is going to be bigger thing that what we expected -- we'll start seeing more back-end usage of .NET.
F# is nice too, and if anyone stayed away because of having to use Windows, maybe now is a time to take a second look.