Initial community discussion thread: dotnet/csharplang#140
public List<int> Prop => field ??= new();
// Uses https://gist.github.com/jnm2/73d378c5b52547728de1148d72de522a | |
/// <summary> | |
/// Leaves the first line alone, but removes common indentation from the remaining lines. | |
/// </summary> | |
public static string RemoveIndentation(string syntax) | |
{ | |
var commonWhitespaceLength = GetCommonWhitespace(syntax).Length; | |
return string.Create( |
public ref struct LineEnumerator(ReadOnlySpan<char> text) | |
{ | |
private ReadOnlySpan<char> text = text == default ? "" : text; | |
public bool MoveNext() | |
{ | |
if (text == default) | |
return false; | |
var nextEnd = text.IndexOf('\n'); |
Initial community discussion thread: dotnet/csharplang#140
public List<int> Prop => field ??= new();
Properties that use the field
keyword will not have warnings such as
For properties that have a get
accessor with a body and which use field
, analyze using this pseudocode, providing the same warnings as we would with accessors as local functions.
void Prop()
{
T? field = default;
declare @schemaName sysname = 'dbo' | |
declare @tableName sysname = 'ItemPrices' | |
declare @rowCondition nvarchar(max) = 'PriceCode in (''SEEDS'', ''YEAREND'')' | |
declare @builder nvarchar(max); | |
select @builder = coalesce(@builder + ' | |
', '') + 'if exists( | |
select *' + QueryWithoutSelect + ') |
flowchart
ICollection --- IEnumerable
IList --- ICollection
IEnumerableT[IEnumerable<T>] --- IEnumerable
ICollectionT[ICollection<T>] --- IEnumerableT
IListT[IList<T>] --- ICollectionT
IReadOnlyCollectionT[IReadOnlyCollection<T>] --- IEnumerableT
IReadOnlyListT[IReadOnlyList<T>] --- IReadOnlyCollectionT
/// <summary> | |
/// Tracks how many references there are to a disposable object, and disposes it when there are none remaining. | |
/// </summary> | |
public sealed class RefCountingDisposer | |
{ | |
private readonly IDisposable disposable; | |
private uint refCount = 1; | |
private readonly object lockObject = new(); | |
/// <summary> |
using System; | |
using System.Threading; | |
internal sealed class DeferredAction | |
{ | |
private static readonly Action SentinelNextSetShouldPost = () => { }; | |
private readonly SynchronizationContext synchronizationContext; | |
private Action scheduledAction = SentinelNextSetShouldPost; |
#if !NET7_0_OR_GREATER | |
namespace System.Runtime.CompilerServices; | |
#endif | |
#if !NET5_0_OR_GREATER | |
internal static class IsExternalInit { } | |
#endif | |
#if !NET7_0_OR_GREATER | |
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Struct, Inherited = false)] |
[TODO: follow standard sections, add examples, flesh everything out]
This is a small feature that removes a common frustration: why do I have to pick a generic type argument when the choice has no effect on the evaluation of the expression? It's very odd to require something to be specified within an operand when it has no impact on the result. Notably, typeof
does not suffer from this limitation.
It's not just about code that better expresses itself. Once some arbitrary type argument has been chosen in a nameof
expression, such as object?
, changing a constraint on a type parameter can break uses of nameof
unnecessarily. Insult becomes added to injury in this scenario. Satisfying the type parameter requires declaring a dummy class to implement an interface which is constraining the type parameter. Now there's unused metadata and a strange name invented, all for the purpose of adding a type argument to the nameof
expression, a type argument which `na