43

Looking at the implementation of CancellationToken.None, it is simply returning default(CancellationToken). However, I see no reference in CancellationToken's documentation that the two are equivalent.

I'd like to offer an API like this but not until I'm sure it'll always work:

Task DoSomething(CancellationToken token = default(CancellationToken))

Is it defined behavior that default(CancellationToken) is the same as CancellationToken.None, or is this just an implementation detail?

i3arnon
  • 113,022
  • 33
  • 324
  • 344
Cory Nelson
  • 29,236
  • 5
  • 72
  • 110
  • It is a struct. So you just get the structure value with all members set to their default. Exact same thing as *new CancellationToken*. Also the reason that lazy's decompiler cannot recover the source code correctly. – Hans Passant Oct 23 '13 at 14:53
  • So is it ok to do this? – tofutim Mar 12 '14 at 17:47
  • 3
    @tofutim No, because the implementation of `CancellationToken.None` is not documented as returning `default(CancellationToken)`, and is therefor free to change. – Cory Nelson Mar 12 '14 at 18:09

5 Answers5

43

After filing an issue with corefx, the documentation remarks have been updated to make this a guaranteed feature:

You can also use the C# default(CancellationToken) statement to create an empty cancellation token.

Cory Nelson
  • 29,236
  • 5
  • 72
  • 110
27

They are the same. Check source code

public static CancellationToken None
{
    get { return default(CancellationToken); }
}

From https://referencesource.microsoft.com/#mscorlib/system/threading/CancellationToken.cs,36b17ded8b1a228c

qxg
  • 6,955
  • 1
  • 28
  • 36
12

CancellationToken.None simply returns new CancellationToken:

public static CancellationToken None
{    
    get
    {
        return new CancellationToken();
    }
}

Thus CancellationToken is a struct, then default(CancellationToken) will return same value. C# Spec 5.2:

For a variable of a value-type, the default value is the same as the value computed by the value-type’s default constructor

UPDATE: This behavior is not defined on MSDN, so you can rely only on current implementation.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • 2
    My question is about if this is *defined behavior*, something I can rely on, or just an implementation detail. – Cory Nelson Oct 23 '13 at 14:10
  • @CoryNelson you can rely only on MSDN documentation, which defines only that token will be non-cancelable. It also says that token will be 'empty' but it does not explains what 'empty' means. Implementation detail can change. But documented behavior also can change. Can you rely on that? If you will not change version of .Net framework you are using, then neither implementation, non behavior will not change. – Sergey Berezovskiy Oct 23 '13 at 14:20
  • Documented behavior does not normally change as per Microsoft's support and backwards compatibility policy. – usr Oct 23 '13 at 14:22
  • @usr `foreach` for example? – Sergey Berezovskiy Oct 23 '13 at 14:22
  • That's why I hedged myself with "normally" :) This is a very rare case. The ratio of changes to non-changes must be in the thousands. – usr Oct 23 '13 at 14:24
  • I just pointed that everything can change :) Nothing is 100% reliable. Only if you will stick to specific version of framework, then you can be sure things will stay same – Sergey Berezovskiy Oct 23 '13 at 14:27
  • 2
    Avoid using a decompiler, that's not what the real source code looks like. Use the Reference Source instead. – Hans Passant Oct 23 '13 at 14:56
2

default is defined for every type. It is null for reference types. It is an "empty" instance for structs, i.e. one with all properties initialized to their respective default values.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • 3
    But is it defined be equivalent to `CancellationToken.None`? – usr Oct 23 '13 at 14:17
  • @usr: No such definition exists, because `CancellationToken.None` is a simple property. And the documentation only states that it returns an empty CancellationToken value. But because `CancellationToken` is a `struct`, we can *assume* that it is equivalent to `default(CancellationToken)`. – Daniel Hilgarth Oct 23 '13 at 15:09
  • 2
    The token returned by `CancellationToken.None` might be different from `default(CancellationToken)` and I see no reason why this cannot be the case. I agree that it isn't and I rely on that in practice. But this question is about guarantees given or not given by Microsoft. – usr Oct 23 '13 at 15:23
1

Yes, they are equivalent. You can check this by using the QuickWatch feature in visual studio:

enter image description here

mamen
  • 1,202
  • 6
  • 26