wasabi-docs-test
  • Introduction
  • README
  • Installation and Debugging
    • Installation
    • Deterministic Build
    • Debugging
  • Deployment
    • Client Deployment
    • Backend Deployment
  • Contributing and Community
    • Contributing
    • Dojo
    • License
    • Report a Vulnerability
  • FAQ
    • FAQ
  • GitBook Tests
    • Links
Powered by GitBook
On this page
  • CodeMaid
  • Comments
  • Asynchronous Locking
  • Null Check
  • Blocking
  • async void
  • Disposing Subscriptions in ReactiveObjects
  • ObservableAsPropertyHelpers Over Properties

Was this helpful?

  1. Contributing and Community

Contributing

CodeMaid

DO use CodeMaid is a Visual Studio extension to automatically clean up your code on saving the file.

CodeMaid is a non-intrusive code cleanup tool. Wasabi's CodeMaid settings can be found in the root of the repository, and are automatically picked up by Visual Studio when you open the project. Assuming the CodeMaid extension is installed. Unfortunately CodeMaid has no Visual Studio Code extension yet. You can check out the progress on this under this GitHub issue.

Comments

DO follow Microsoft's C# commenting conventions.

  • Place the comment on a separate line, not at the end of a line of code.

  • Begin comment text with an uppercase letter.

  • End comment text with a period.

  • Insert one space between the comment delimiter (//) and the comment text, as shown in the following example.

  • Do not create formatted blocks of asterisks around comments.

// The following declaration creates a query. It does not run
// the query.

Asynchronous Locking

DO NOT use mix awaitable and non-awaitable locks.

// GOOD
private AsyncLock AsyncLock { get; } = new AsyncLock();
using (await AsyncLock.LockAsync())
{
    ...
}

// GOOD
private object Lock { get; } = new object();
lock (Lock)
{
    ...
}

// BAD
using (AsyncLock.Lock())
{
    ...
}

Null Check

DO use is null instead of == null. It was a performance consideration in the past but from C# 7.0 it does not matter anymore, today we use this convention to keep our code consisent.

    if (foo is null) return;

Blocking

DO NOT block with .Result, .Wait(), .GetAwaiter().GetResult(). Never.

// BAD
IoHelpers.DeleteRecursivelyWithMagicDustAsync(Folder).GetAwaiter().GetResult();

async void

DO NOT async void, except for event subscriptions. async Task instead. DO try catch in async void, otherwise the software can crash.

{
    MyClass.SomethingHappened += MyClass_OnSomethingHappenedAsync;
}

// GOOD
private async void Synchronizer_ResponseArrivedAsync(object sender, EventArgs e)
{
    try
    {
        awat FooAsync();
    }
    catch (Exception ex)
    {
        Logger.LogError<MyClass2>(ex);
    }
}

Disposing Subscriptions in ReactiveObjects

DO follow ReactiveUI's Subscription Disposing Conventions.

DO dispose your subscription if you are referencing another object. DO use the .DisposeWith() method.

Observable.FromEventPattern(...)
    .ObserveOn(RxApp.MainThreadScheduler)
    .Subscribe(...)
    .DisposeWith(Disposables);

DO NOT dispose your subscription if a component exposes an event and also subscribes to it itself. That's because the subscription is manifested as the component having a reference to itself. Same is true with Rx. If you're a VM and you e.g. WhenAnyValue against your own property, there's no need to clean that up because that is manifested as the VM having a reference to itself.

this.WhenAnyValue(...)
    .ObserveOn(RxApp.MainThreadScheduler)
    .Subscribe(...);

ObservableAsPropertyHelpers Over Properties

DO follow ReactiveUI's Oaph Over Properties Principle.

DO use ObservableAsPropertyHelper with WhenAny when a property's value depends on another property, a set of properties, or an observable stream, rather than set the value explicitly.

public class RepositoryViewModel : ReactiveObject
{
  readonly ObservableAsPropertyHelper<bool> _canDoIt;

  public RepositoryViewModel()
  {
    _canDoIt = this.WhenAny(...)
        .ObserveOn(RxApp.MainThreadScheduler)
        .ToProperty(this, x => x.CanDoIt);
  }

  public bool CanDoIt => _canDoIt?.Value ?? false;
}
PreviousBackend DeploymentNextDojo

Last updated 5 years ago

Was this helpful?