Skillnader
När jag först satte mig bakom tangentbordet för att skriva C# tyckte jag att själva tänket bakom språket kändes mer användarvänligt än Java. Kanske för att koden är mindre pratig och då blir mer lättläst. Jag gillar till exempel att man inte explicit behöver skriva ut getters och setters. I Java har jag stört mig lite på att man alltid behöver skriva ut allt. Det finns ju bibliotek som Lombok som gör att man kan använda färdiga annoteringar, men ändå, skönt att det redan är inbyggt och man kan slippa. Ett exempel på vad jag menar:
// Exempel i Java (utan Lombok eller dylikt)
public class ExampleClass {
private String myFavouriteAnimal;
public ExampleClass(String animal) {
this.myFavouriteAnimal = animal;
}
public String getMyFavouriteAnimal() {
return myFavouriteAnimal;
}
public void setMyFavouriteAnimal(String newAnimal) {
this.myFavouriteAnimal = newAnimal;
}
}
// Samma sak i C#
public class ExampleClass
{
public string MyFavouriteAnimal { get; set; }
}
Pakethantering utan kommandon
Detta är ju kanske mer en IDE-grej men jag gillar också att pakethanteringen i Visual Studio är “automatisk”: jag behöver inte sitta och installera paket med olika kommandon utan det sker automatiskt när man öppnar en solution. Visual Studios pakethanterare ger även en bra överblick över vilka paket som finns installerade och UI:t gör det lätt att upp- eller nedgradera och konfigurera som man vill.
Async/await i stället för monos och fluxar
Async/await i C# är mer likt det jag är van vid från min frontendbakgrund så kanske är därför jag tycker att det är tydligare. Jag förstår use caset för reaktiv programmering ifall man har en applikation som behöver kunna hantera en massa trafik samtidigt, men det känns ändå som att det är onödigt krångligt i Java med alla monos, fluxar, streams, zips, maps och flatMaps. I Java 25 ska det dock komma nya grejer som i kombo med virtual threads förenklar hur det funkar, men i C# har ett (enligt mig) tydligare sätt att jobba med asynkron kod funnits länge.
Nedan följer ett exempel på hur jag är van vid att reaktivt hämta något i Java. På det här sättet går det inte att spara något i en variabel och vänta på det, utan man behöver kedja en massa saker och se till att man är subscribeat till rätt mono:
public Mono<UserOrdersResponse> getUserOrdersSummary(@PathVariable int id) {
return userBackendApi.get(id)
.flatMap(user ->
orderBackendApi.getByUserId(user.getId())
.map(orders -> {
log.info("{} has {} orders", user.getName(), orders.size());
return new UserOrdersResponse(user, orders);
})
);
}
// Hämta något asynkront i C#, det går dessutom att spara i en variabel
var user = await userBackendApi.GetAsync(1);
var orders = await orderBackendApi.GetByUserIdAsync(user.Id);
Console.WriteLine($"{user.Name} {orders.Count}");
Det jag saknar: method references
Vidare till något jag saknar lite med Java vilket är Lambda Method References. Tycker det blir snyggt när man bakar ihop kod så det blir mer koncist (väldigt olikt Java i övrigt).
List<String> famousDogs = Arrays.asList("Goofy", "Pluto", "Lassie", "Lady", "The Tramp", "Scooby-Doo", "Hachiko");
// Utan method references
List<String> sorted = famousDogs.stream()
.sorted((a, b) -> a.compareTo(b))
.collect(Collectors.toList());
// Med method references
List<String> sorted = famousDogs.stream()
// på raden nedan skriver jag bara String::compareTo istället för att skriva ut hela lambdan
.sorted(String::compareTo)
.collect(Collectors.toList());
Något jag hade hoppats på
Eftersom Anders Hejlsberg ligger bakom både TypeScript och C# hade jag hoppats att TypeScripts Union Types skulle dyka upp i C#, men tyvärr inte. Dock finns ju generiska typer, så får hålla till godo med det.
// Union types i TypeScript
type Fruit = 'banana' | 'pineapple';
// Ett sätt att göra samma sak i C#
public enum Fruit
{
Banana,
Pineapple
}
Slutord
Slutligen tycker jag inte att ena språket är bättre än det andra. Förutom att hålla på med problemlösning är det som jag framför allt tycker är roligt med att vara utvecklare att jag ständigt får lära mig nya saker. Under min första tid som Decernian har det varit roligt att sitta och fundera över skillnader, likheter och preferenser mellan de olika språken jag kan. Vem vet, kanske har du som läser också blivit inspirerad till att börja fundera över likheter och skillnader mellan det du lärt dig under din karriär.