Moving From C# To Dart: Quick Start

Moving from C# to Dart is very easy due to its similar style and syntax. However, with every language comes differences that will make things easier, and other things harder. This quick start guide is here to quickly run down what you need to know to transition to Dart. It doesn’t cover anything, but only some of the basics to make the transition as easy as possible.

Syntax, Operator & Naming Variations

Starting with the basics, I’ll cover some of the most common syntax and other variations.

  • Everything is null in Dart, including what we would call value types in C#.
// no need for ? sign to signal nullable.
int myVariable = null;

// Null checking
if (myVariable != null)

// These work the same way as C#.
myVariable = myVariable ?? 0; // Assigns 0 if null

// Short circuits also work.
myVariable?.toString();

Personally this one scares me a bit, because you have a to check for nulls on absolutely everything. An issue to support non-nullable types is open, and being worked on.

  • Accessibility Modifiers

Use an underscore to mark a class or method private, otherwise its public.

class _PrivateClass {

}

class PublicClass {  
  String _privateField;
  String publicField;
}
  • Generics

Generics are very similar to C#, with an exception that you can pass a generic class without the Type constraint.

class State<Type>
{
  Type getValue() => null;
} 
void processState(State state) { 
  dynamic value = state.getValue(); 
} 
void processStateWithType(State<String> state) { 
  String value = state.getValue(); 
}
  • Delegates

Delegates are essentially function pointers. In Dart you can use a typedef to define a method signature and hold an instance of this in a variable.

typedef void MyFunction(int value);

void main() {
  MyFunction function = myFunction;
}

void myFunction(int value) => value * 2;
  • Optional new

Dart can figure out when you are defining a new element, hence you don’t need to say new if you don’t want to.

void main() {
  var instance = new List();
  var alsoInstance = List();
}
  • Dictionaries & Lists

Lists are lists, and Dictionaries are Maps.

var list = new List();
var dictionary = new Map<String, String>();

Interfaces & Inheritance

Dart doesn’t have interfaces, you have abstract classes. You implement abstract classes.

abstract class BaseClass {
  abstract void myFunction();
}

class MyClass implements BaseClass {
  void myFunction() {
    // do something
  }
}

If you want to inherit, you extend classes.

class BaseClass {
  void myFunction() {}
}

class MyClass extends BaseClass {
  void myOtherFunction() {
    // do something
  }

  // every function is overridable in Dart.
  @override
  void myFunction() {
    // do something
  }
}

You can extend a class and implement multiple classes. Dart also supports Mixin’s. A Mixin is like attaching a class and adding its functionality to the class, without actually inheriting from it. This is also similar to C# 8.0’s interface implementations.

class MyMixin {
  void sayHello() => print('Hello!');
}

class MyClass with MyMixin
{ 
}

Now you can call sayHello() from MyClass. You can add as many Mixins as you want, as well as extend and implement other classes.

Namespaces

Dart doesn’t have namespaces. Instead you import packages or files as such.

// Import a core dart library
import 'dart:async';

// Import a package
import 'package:flutter/material.dart';

// Import another file in your application
import 'myfilename.dart';

This gives you access to all the classes and functions inside the file. But if there is a name conflict or you want to make things a little more readable, you can name them.

import 'myfilename.dart' as filename;

// In my code I now go
filename.myFunctionName();

Further to this, you can have functions directly in files, without a class or namespace. This is fantastic if you want to program more functionally. e.g. you can put this in a file all by itself, nothing else needed.

void myFunctionName() {
  // Do something
}

Core Libraries

Similar to .NET libraries, these Dart libraries include core functionality common with most apps.

dart:core is automatically available. It includes:

  • Numbers
  • Strings
  • Booleans
  • Collections
  • Date & Times
  • Exceptions
  • and more

dart:async is much like the System.Threading namespace and includes:

  • Future – is similar to a Task. I go into more detail on this in Flutter Threading.
  • Stream – is sort of like an event, but thought of more as a stream of data that you listen to, and act upon as data is received.
  • More on these will be included below.

dart:math is very similar to System.Math.

dart:io is very similar to System.IO.

Async/Await

Asynchronous programming in Dart is also very similar to C#. You use the Future class instead of Task. The async and await keywords are the same, the only minor difference is the async keyword placement, which is after the method name, instead of before.

void main() async {
  var result = await myFunction();
}

Future<String> myFunction() {
  // Similar to Task.FromResult
  return Future.value('Hello');
}

I go into much more detail about this in Flutter Threading: Isolates, Future, Async and Await.

Events

Instead of an event in C# holding delegates, that then all get called when an event is raised, Dart works in Streams. A stream is similar to an event, but you open it, listen to it, and close it.

StreamController streamController = new StreamController.broadcast();

void main() {
  streamController.stream.listen((args) => {
        // do something
      });

  streamController.add("hello");

  streamController.close();
}

The benefit of this approach is you can do many things such as transform values, or pause events for a certain period of time and much more. If you are familiar with Rx.NET, then Streams are like Observables.

What you will gain

Some additional language features that I found useful, that C# doesn’t have.

  • Null Assignment Operator (??=)
void main() {
  String value;
  value ??= 'Hello'; // If value is null, assign 'Hello' to it.
}
  • Cascading Expressions

You may be used to a Fluent API in C#, where you would use extension methods to allow you to keep working on the same object. In Dart, you get this for free with cascading expressions. This also helps you avoid creating a variable to reference.

class MyClass {
  void myFunction() {}
  void myOtherFunction() {}
  void myOtherOtherFunction() {}
}

void main() {
  MyClass()
    ..myFunction()
    ..myOtherFunction()
    ..myOtherOtherFunction();
}
  • Dynamic keyword

I know that the dynamic keyword is available in C#, however if you have ever developed an app for Xamarin.iOS, you will be aware that you can’t use this. In Dart, is this available for you on iOS.

  • Auto assigning constructor parameters

If you want to pass in a variable directly into a class then store it in a field, in C# you need to define this inside the constructor method body. In Dart, you can have this done automatically for you. In this example, field is automatically assigned, by using the this keyword.

class MyClass {
  
  MyClass(this.field);

  String field;
}

What you will miss

Languages have their strengths and weaknesses. Coming from C# you may miss these language features.

Packages

The equivalent of Nuget in Data is pub.dartlang.org. You can search for packages made by Google or 3rd parties. If you want to add a package to your Flutter project, instead of a packages.config or references in your csproj files, you will modify the dependency section of your pubspec.yaml file.

dependencies:
  http: "^0.12.0"
  http_retry: ^0.1.1+3
  flutter:
    sdk: flutter

Summary

Dart and C# are quite similar in syntax, and even have common library names. If you are proficient in C#, you will find it very easy to work with Dart. There are more differences that I didn’t go through, but I have hopefully covered the major ones to will help you transition.

If you are coming from Xamarin.Forms, I originally wrote the documentation Flutter for Xamarin.Forms developers, in which Google now updates and maintains. It provides a great walk through of common concepts in Xamarin.Forms and how it is done in Flutter.

Share on
© 2019 Adam Pedley