Hacker News new | past | comments | ask | show | jobs | submit login
Understanding .NET 2015 (msdn.com)
187 points by pjmlp on Feb 26, 2015 | hide | past | favorite | 104 comments



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.

[1]: https://msdn.microsoft.com/en-us/library/system.threading.sy...


Check out https://github.com/paulcbetts/refit && https://github.com/akavache/Akavache && https://github.com/michael-wolfenden/Polly

Then check out 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.


It'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.


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();
    }
  }
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-sam... or more consise builder pattern http://benjiweber.co.uk/blog/2014/11/02/builder-pattern-with...


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.


Having to rely on reflection is bad though.


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#.


A killer feature of the Ceylon programming language is its typesafe metamodel. Metamodel references are refactored like everything else in eclipse.


Absolutely. My point is just that the Java generics not being available at runtime is a common complaint, but it's only partially true.

Most of the issues can actually be resolved even with type erasure. e.g. method overloading can be resolved statically.


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.

[1] https://github.com/pocorall/scaloid

[2] https://github.com/scala/async


Yes, the problem can be solved by using a different language. I'm pretty sure that was the point.


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.

Cheers,


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'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.


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 spend most of my time in C# and it's always a sad moment when I start typing .Where(x => ...) in another language and realize it doesn't exist.



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.


That's basically what filter does in Clojure (and probably any other language with lazy evaluation): http://debasishg.blogspot.com/2010/05/laziness-in-clojure-so...


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.


The comment replied to was about missing its like in other languages. Didn't mean to imply that its name should be changed in C#.


Not sure why this is getting downvoted, that's what it's called in most other languages.


Nah, it's spelled Select: http://www.w3schools.com/sql/sql_where.asp

(but academics like non-human-friendly terms, sure)


No.

Select == Map

Where == Filter

SelectMany == FlatMap

Aggregate == FoldL


No idea what point you're trying to make.

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'm primarily a C# guy, but whenever I touch JS, i find Underscore indispensable.


perhaps these two projects would interest you?

https://linqjs.codeplex.com/ http://underscorejs.org/


It's pretty trivial to implement Linq-like functions in JavaScript, or, I think stuff like undersocre has them.


It is and it isn't. LINQ is actually incredibly smart under the hood, so if I ran:

    myList.Where(x => x.name = 'Person');
          .Where(x => x.age > 18);
          .ToList();
it wouldn't actually run two different array filters - it would combine them. You can imagine the performance gains to be had there.


Citation? I was unaware that the little IEnumerable functions did fusion. If you mean an IQueryable execution, like LINQ-To-SQL, then sure.


LINQ IEnumerable functions are implemented using the `yield return` operator:

  public static IEnumerable<T> Where<T>(IEnumerable<T> source, 
                                        Predicate<T> predicate)
  {
    foreach(var item in source)
    {
      if(predicate(item))
        yield return item;
    }
  }
which means

  var results = myList
    .Where(x => x.name == 'Person');
    .Where(x => x.age > 18);
    .ToList();
is executed just like

  var results = new List<Foo>();
  foreach(var x in myList)
  {
    if(x.name == 'Person')
    {
      if(x.age > 18)
        results.Add(x);
    }
  }


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.)


There is no missing foreach loop because LINQ iterators are smart enough to combine predicates whenever possible (source here: http://referencesource.microsoft.com/#System.Core/System/Lin..., see line 204 when dealing with arrays).

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.


Ah, that's a cool optimization.

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.)

1: http://pastebin.com/7J9FErWN


It is not so bad in JavaScript anymore. With Lodash:

    _(myList)
        .filter(x => x.name == 'Person')
        .filter(x => x.age > 18)
        .value()
Used like this Lodash is lazy, so the first value of myList will run through all the filters before the next item gets processed.


Well, underscore offers this, from the docs:

_.where(listOfPlays, {author: "Shakespeare", year: 1611});


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).

[0]: https://lodash.com/

[1]: https://lodash.com/docs#_


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!


Python for smaller self-contained projects and scripting.

Erlang/Elixir for larger projects where fault tolerance or concurrency is needed.

C/C++ where GC is a no-go (games, low latency, time critical data processing).

Next up in the pipeline to learn and use: Rust


> games

Ever played something like e.g. Bastion?

http://en.wikipedia.org/wiki/Bastion_%28video_game%29

I mean if you are developing the new Unreal Engine - sure. But otherwise gaming industry would benefit from more of maintainable code.


For context, Bastion was written in C#.

Here's what the lead developer said on the topic of GC:

http://www.reddit.com/r/IAmA/comments/lwljh/iama_dev_team_of...



It's simple: when looping either make stuff quick to collect or make it never collect.


I'd love to see a comparison of Golang's goroutines/channels vs async. If you know of one or could write one here, that would be appreciated! :-)


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.


What is the bind semantic in rx?


For a FRP RX user interface example check out the front page of http://www.reactiveui.net/ (or scroll up a bit where I posted the viewmodel code).

For example of a RX backend API check out https://github.com/AdaptiveConsulting/ReactiveTrader


"we'll start seeing more back-end usage of .NET." Outside of startup world, it is already used everywhere.


Well, I can assure you that Java is used.. more everywhere.


From itjobswatch.co.uk:

C# - 16748 jobs [1]; Java - 13816 jobs [2]

[1] http://www.itjobswatch.co.uk/jobs/uk/csharp.do

[2] http://www.itjobswatch.co.uk/jobs/uk/java.do


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.

From indeed.com:

Java - 81,818 [1]; C# - 35,623 [2];

[1] http://www.indeed.com/jobs?q=java&l=

[2] http://www.indeed.com/jobs?q=C%23&l=

comments:

- Java has more results than even ".NET", which encompasses more than just C#: 73,971 http://www.indeed.com/jobs?q=.NET&l=

- C# has about the same number of results as Python: 35,072 http://www.indeed.com/jobs?q=python&l=

From StackOverflow:

Java - 794 [1]; C# - 479 [2]

[1] http://careers.stackoverflow.com/jobs?searchTerm=java

[2] http://careers.stackoverflow.com/jobs?searchTerm=C%23

From indeed.co.uk (the only one that has a similar ratio as itjobswatch.co.uk):

Java - 25,478 [1]; C# - 28,037 [2]

[1] http://www.indeed.co.uk/jobs?q=java&l=

[2] http://www.indeed.co.uk/jobs?q=C%23&l=

From indeed.com, Bay Area:

Java - 5,997 [1]; C# - 1,013 [2]

[1] http://www.indeed.com/jobs?q=java&l=San+Francisco%2C+CA&radi...

[2] http://www.indeed.com/jobs?q=C%23&l=San+Francisco%2C+CA&radi...

From indeed.com, New York:

Java - 6,941 [1]; C# - 2,548 [2]

[1] http://www.indeed.com/jobs?q=java&l=New+York%2C+NY&radius=25

[2] hhttp://www.indeed.com/jobs?q=C%23&l=New+York%2C+NY&radius=25

From indeed.com, Seattle:

Java - 3,832 [1]; C# - 2,124 [2]

[1] http://www.indeed.com/jobs?q=java&l=Seattle%2C+WA

[2] http://www.indeed.com/jobs?q=C%23&l=Seattle%2C+WA


He meant like COBOL - wider historical spread (despite declining workforce).


On Linux though?


I am python developer, I am looking forward to program in F#. F# just seems right after developing with python unlike languages like c#, java.


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.


Yes! <3 F# :)


Plus if you run - it works.


There are spelling squiggles in the article's first image :]

http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-bl...

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?


Any reasons I should switch to Java or other technologies?

What I get with the (much hated) Microsoft stack:

- C# with LINQ and async await

- Roslyn compiler as a service which speeds up development

- mature .NET framework

- more and more open source and cross platform parts and smaller independent libs

- typescript

- Xamarin cross platform tools

I also use python and used Java in the past. I don't see any reason why Java should be better?


- JRebel or Spring Loaded

- 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.


performance? https://www.techempower.com/benchmarks/

I am wondering how asp.net on linux will stack up! should be interesting.


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.

Was hard to know where to start.


.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 looks like the open source cross-platform version of .NET, v5 ("core"?), is something that was written completely from scratch?

Why wouldn't they open source the v4.x version? And why is WPF, Windows Forms, and ASP.NET placed above the .NET 4.x block in the diagram?

Is .NET v5 Core a from-scratch lightweight reimplementation that can't run the full stack? If not, why the huge separation?


It is fairly clear on the GitHub repositories.

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.


Thanks for clarifying.

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...?


It doesn't depend on Win32, but MilCore depends on DirectX 9, so I guess it would be hard to port to other platforms.


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.


That's what I'm asking. It's very unclear, even when reading stuff like http://blogs.msdn.com/b/dotnet/archive/2014/12/04/introducin...

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."

[1] http://www.dotnetfoundation.org/netcore5


They didn't develop it in git, just dumped it in github. That explains the lack of commits.

I don't see how the quote substantiates the notion that .NET core is written from scratch.


The discussion in this corefx github issue is pretty interesting to follow.

https://github.com/dotnet/corefx/issues/973

It probably answers a few of the questions several have asked in this thread with regards to what the .NET Core is.


I thought Microsoft was phasing out .NET and encouraging people to write their GUIs in JavaScript. That's what they were saying early last year.


They never said that. WinJS was just another possibility alongside .NET and C++/CX.


I think you're confused in a couple respects.


.NET has been their recommended enterprise platform for a long time. They came out with a JavaScript based environment for competition with mobile.


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.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: