Agent skill

Csharp Nullable Types

by sketch7 in sketch7/FluentlyHttpClient

A skill your agent uses when C nullable reference types, null safety patterns, and migration strategies.

MITAuto-check: notesDevelopment

Install Csharp Nullable Types

skills CLI
$ npx skills add sketch7/FluentlyHttpClient --skill csharp-nullable-types -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install sketch7/FluentlyHttpClient csharp-nullable-types --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/sketch7/FluentlyHttpClient.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/csharp-nullable-types .claude/skills/csharp-nullable-types && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
csharp-nullable-types
GitHub stars
121
Used in
1 other repo
Token cost
~5.7k tokens
SKILL.md length
459 words
Files
1
Skills in repo
4
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when C nullable reference types, null safety patterns, and migration strategies.

  • Works in 10 steps: Enable Nullable Globally: Use enable in… → Explicit Nullability: Make nullability… → Validate at Boundaries: Check for null… → …
  • C nullable reference types
  • SKILL.md covers Nullable Reference Types (C# 8+), Nullable Value Types, Null Safety Annotations and Null-Forgiving Operator, plus 8 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Csharp Nullable Types is an agent skill from sketch7/FluentlyHttpClient. Use when C nullable reference types, null safety patterns, and migration strategies. Use when ensuring null safety in C code.

Its SKILL.md is about 5.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development. It works with C#. The repository describes itself as: Http Client for .NET Standard with fluent APIs which are intuitive, easy to use and also highly extensible. The licence is MIT.

When your agent uses it

  • C nullable reference types
  • Null safety patterns
  • Migration strategies
  • Ensuring null safety in C code

Example prompts

  • “/csharp-nullable-types”

Requirements

  • Pre-approved tools (allowed-tools): Bash, Read, Write, Edit

Workflow steps

10 steps, taken from the first numbered list in SKILL.md.

  1. Enable Nullable Globally: Use enable in .csproj
  2. Explicit Nullability: Make nullability intentions clear in APIs
  3. Validate at Boundaries: Check for null at public API boundaries
  4. Use Null-Conditional Operators: Prefer ?. over explicit null checks
  5. Avoid Null-Forgiving: Use ! sparingly and only when truly necessary
  6. Return Non-Nullable: Prefer non-nullable return types when possible
  7. Use Annotations: Apply [NotNull], [MaybeNull] etc. appropriately
  8. Constructor Initialization: Initialize non-nullable properties in constructors
  9. Throw on Invalid State: Throw exceptions for unexpected nulls
  10. Gradual Migration: Migrate file-by-file with #nullable directives

What it can do on your machine

Read from SKILL.md and the folder at commit 397ee9b. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Bash
    • Read
    • Write
    • Edit

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are csharp).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • learn.microsoft.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Csharp Nullable Types loads about 5.7k tokens when it runs. Until then it costs about 37 tokens; SKILL.md has 459 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~37
When it runs · the whole SKILL.md, loaded when a task matches
~5.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NotePre-approves every shell command (allowed-tools: Bash)SKILL.md
    allowed-tools: Bash, Read, Write, Edit

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from sketch7/FluentlyHttpClient at commit 397ee9b, republished under its MIT licence (© sketch7). 459 words, ~5,725 tokens.

Download SKILL.mdSave it as .claude/skills/csharp-nullable-types/SKILL.md (or your agent's skills folder).
name
csharp-nullable-types
description
Use when C# nullable reference types, null safety patterns, and migration strategies. Use when ensuring null safety in C# code.
allowed-tools
Bash, Read, Write, Edit
user-invocable
false

C# Nullable Types

Master nullable reference types, null safety patterns, and migration strategies in C# 8+. This skill covers nullable value types, nullable reference types, null-safety annotations, operators, and best practices for writing null-safe code.

Nullable Reference Types (C# 8+)

Nullable reference types provide compile-time null safety by distinguishing between nullable and non-nullable reference types.

Enabling Nullable Context
csharp
// Project-wide in .csproj
<PropertyGroup>
    <Nullable>enable</Nullable>
</PropertyGroup>

// File-level directive
#nullable enable

public class User
{
    // Non-nullable - must be initialized
    public string Name { get; set; } = string.Empty;

    // Nullable - can be null
    public string? MiddleName { get; set; }

    // Non-nullable - must be set in constructor
    public string Email { get; set; }

    public User(string email)
    {
        Email = email;
    }
}

// Disable for legacy code
#nullable disable

public class LegacyClass
{
    public string Name { get; set; } // Warning suppressed
}

#nullable restore // Return to project default
Non-nullable and Nullable References
csharp
#nullable enable

public class PersonService
{
    // ✅ Non-nullable parameter and return type
    public string FormatName(string firstName, string lastName)
    {
        return $"{firstName} {lastName}";
    }

    // ✅ Nullable parameter
    public string FormatNameWithMiddle(string firstName, string? middleName, string lastName)
    {
        if (middleName != null)
        {
            return $"{firstName} {middleName} {lastName}";
        }
        return $"{firstName} {lastName}";
    }

    // ✅ Nullable return type
    public string? FindUserEmail(int userId)
    {
        var user = _repository.Find(userId);
        return user?.Email; // May return null
    }

    // ⚠️ Warning - possible null reference
    public string GetUpperName(string? name)
    {
        // CS8602: Possible null reference
        return name.ToUpper();
    }

    // ✅ Fixed with null check
    public string GetUpperNameSafe(string? name)
    {
        if (name == null)
        {
            throw new ArgumentNullException(nameof(name));
        }
        return name.ToUpper();
    }
}

Nullable Value Types

Value types can be made nullable using Nullable<T> or the ? syntax.

Nullable<T> and T?
csharp
public class NullableValueTypes
{
    // Nullable value types
    public int? Age { get; set; }
    public DateTime? BirthDate { get; set; }
    public decimal? Salary { get; set; }
    public bool? IsActive { get; set; }

    // Equivalent to:
    public Nullable<int> AgeVerbose { get; set; }

    public void WorkWithNullables()
    {
        int? value = null;

        // HasValue and Value properties
        if (value.HasValue)
        {
            int actualValue = value.Value;
            Console.WriteLine(actualValue);
        }

        // GetValueOrDefault
        int result1 = value.GetValueOrDefault(); // 0
        int result2 = value.GetValueOrDefault(42); // 42

        // Null coalescing
        int result3 = value ?? 100; // 100
    }

    public int CalculateAge(DateTime? birthDate)
    {
        // ⚠️ Warning - possible null reference
        // return DateTime.Now.Year - birthDate.Value.Year;

        // ✅ Correct with null check
        if (!birthDate.HasValue)
        {
            throw new ArgumentException("Birth date is required", nameof(birthDate));
        }

        return DateTime.Now.Year - birthDate.Value.Year;
    }
}
Nullable Value Type Operations
csharp
public class NullableOperations
{
    public void ArithmeticOperations()
    {
        int? a = 5;
        int? b = 10;
        int? c = null;

        // Arithmetic with nullables
        int? sum = a + b; // 15
        int? nullSum = a + c; // null

        // Comparison
        bool? equal = a == b; // false
        bool? nullEqual = a == c; // null (neither true nor false)

        // Lifted operators
        int? result = (a > 0) ? a * 2 : null;
    }

    public decimal? CalculateDiscount(decimal? price, decimal? discountPercent)
    {
        // If either is null, result is null
        return price * (1 - discountPercent / 100);
    }

    public void BooleanLogic()
    {
        bool? a = true;
        bool? b = false;
        bool? c = null;

        // Three-valued logic
        bool? and1 = a & b;  // false
        bool? and2 = a & c;  // null
        bool? and3 = b & c;  // false (false & anything = false)

        bool? or1 = a | b;   // true
        bool? or2 = a | c;   // true (true | anything = true)
        bool? or3 = b | c;   // null
    }
}

Null Safety Annotations

Attributes that provide additional null-safety information to the compiler.

Common Annotations
csharp
using System.Diagnostics.CodeAnalysis;

public class AnnotationExamples
{
    // [NotNull] - Parameter won't be null when method returns normally
    public void ProcessUser([NotNull] User? user)
    {
        if (user == null)
        {
            throw new ArgumentNullException(nameof(user));
        }

        // Compiler knows user is not null here
        Console.WriteLine(user.Name);
    }

    // [MaybeNull] - Return value may be null even if type is non-nullable
    [return: MaybeNull]
    public T GetValueOrDefault<T>(string key)
    {
        if (_dictionary.TryGetValue(key, out var value))
        {
            return value;
        }
        return default; // May be null for reference types
    }

    // [NotNullWhen] - Parameter is not null when method returns specified bool
    public bool TryGetUser(int id, [NotNullWhen(true)] out User? user)
    {
        user = _repository.Find(id);
        return user != null;
    }

    public void UseUser(int id)
    {
        if (TryGetUser(id, out var user))
        {
            // Compiler knows user is not null here
            Console.WriteLine(user.Name);
        }
    }

    // [NotNullIfNotNull] - Return value is not null if parameter
    // is not null
    [return: NotNullIfNotNull(nameof(value))]
    public string? ProcessString(string? value)
    {
        return value?.Trim().ToUpperInvariant();
    }

    // [DoesNotReturn] - Method never returns normally
    [DoesNotReturn]
    public void ThrowError(string message)
    {
        throw new InvalidOperationException(message);
    }

    public void ValidateUser(User? user)
    {
        if (user == null)
        {
            ThrowError("User is required");
        }

        // Compiler knows this is unreachable if user is null
        Console.WriteLine(user.Name);
    }
}
MemberNotNull Annotation
csharp
public class InitializationExample
{
    private string _name;
    private string _email;

    public InitializationExample()
    {
        Initialize("Default", "default@example.com");
    }

    // Tells compiler these members are initialized
    [MemberNotNull(nameof(_name), nameof(_email))]
    private void Initialize(string name, string email)
    {
        _name = name;
        _email = email;
    }

    [MemberNotNull(nameof(_name), nameof(_email))]
    public void Reset()
    {
        _name = string.Empty;
        _email = string.Empty;
    }
}

Null-Forgiving Operator

The null-forgiving operator (!) suppresses nullable warnings when you know better than the compiler.

Using the ! Operator
csharp
public class NullForgivingExamples
{
    private User? _currentUser;

    public void Initialize()
    {
        _currentUser = LoadUser();
    }

    public void ProcessCurrentUser()
    {
        // ⚠️ Warning: Possible null reference
        // Console.WriteLine(_currentUser.Name);

        // ✅ Use ! when you know it's not null
        Console.WriteLine(_currentUser!.Name);
    }

    // ⚠️ Use sparingly and carefully
    public string GetUserName()
    {
        // Only use ! if you're absolutely sure
        return _currentUser!.Name;
    }

    // ✅ Better: check explicitly
    public string GetUserNameSafe()
    {
        if (_currentUser == null)
        {
            throw new InvalidOperationException("User not initialized");
        }

        return _currentUser.Name;
    }

    // Common pattern with dictionary
    public void DictionaryPattern()
    {
        var dict = new Dictionary<string, User>();
        dict["key"] = new User("test@example.com");

        // You know key exists
        var user = dict["key"];
        Console.WriteLine(user.Email); // No warning needed

        // But with TryGetValue
        if (dict.TryGetValue("key", out var foundUser))
        {
            // foundUser is User?, but you know it's not null here
            Console.WriteLine(foundUser!.Email); // Or better: check in if
        }
    }
}
When NOT to Use the Null-Forgiving Operator
csharp
public class BadNullForgiving
{
    // ❌ BAD - Hiding real problems
    public void ProcessData(string? input)
    {
        var result = input!.ToUpper(); // Will crash if input is null
    }

    // ✅ GOOD - Proper null handling
    public void ProcessDataSafe(string? input)
    {
        if (input == null)
        {
            throw new ArgumentNullException(nameof(input));
        }

        var result = input.ToUpper();
    }

    // ❌ BAD - False confidence
    public User GetUser(int id)
    {
        return _repository.Find(id)!; // May actually be null!
    }

    // ✅ GOOD - Handle null case
    public User GetUserSafe(int id)
    {
        return _repository.Find(id)
            ?? throw new KeyNotFoundException($"User {id} not found");
    }
}

Null-Conditional Operators

Safe navigation operators for accessing members that might be null.

?. and ?[] Operators
csharp
public class NullConditionalExamples
{
    public void SafeNavigation()
    {
        User? user = GetUser();

        // ✅ Null-conditional member access
        string? name = user?.Name; // null if user is null

        // ✅ Chaining null-conditional operators
        string? city = user?.Address?.City;

        // ✅ Null-conditional indexing
        char? firstChar = user?.Name?[0];

        // ✅ Combining with method calls
        int? nameLength = user?.Name?.Length;

        // ✅ With null coalescing
        string displayName = user?.Name ?? "Guest";

        // ✅ Null-conditional with invocation
        int? result = user?.CalculateAge();
    }

    public void ArrayAndCollectionAccess()
    {
        int[]? numbers = GetNumbers();

        // ✅ Null-conditional array access
        int? first = numbers?[0];

        // ✅ Null-conditional with LINQ
        int? max = numbers?.Max();

        // ✅ Dictionary access
        Dictionary<string, User>? users = GetUsers();
        User? user = users?["key"];
    }

    public void InvocationExamples()
    {
        Action? callback = GetCallback();

        // ✅ Null-conditional invocation
        callback?.Invoke();

        // Equivalent to:
        if (callback != null)
        {
            callback.Invoke();
        }

        // ✅ With events
        EventHandler? handler = SomeEvent;
        handler?.Invoke(this, EventArgs.Empty);
    }
}

Null-Coalescing Operators

The ?? and ??= operators provide default values for null expressions.

?? Operator
csharp
public class NullCoalescingExamples
{
    public void BasicCoalescing()
    {
        string? name = GetName();

        // ✅ Provide default if null
        string displayName = name ?? "Unknown";

        // ✅ Chain multiple coalescing
        string result = GetPrimaryName()
            ?? GetSecondaryName()
            ?? GetDefaultName()
            ?? "Fallback";

        // ✅ With value types
        int? nullableValue = GetValue();
        int value = nullableValue ?? 0;

        // ✅ Combine with null-conditional
        int length = user?.Name?.Length ?? 0;
    }

    public User GetUserOrDefault(int id)
    {
        // ✅ Return default if null
        return _repository.Find(id) ?? new User("guest@example.com");
    }

    public string GetConfigValue(string key, string defaultValue)
    {
        // ✅ Configuration pattern
        return _config[key] ?? defaultValue;
    }
}
??= Operator (Null-Coalescing Assignment)
csharp
public class NullCoalescingAssignment
{
    private User? _cachedUser;
    private List<string>? _items;

    public User GetUser(int id)
    {
        // ✅ Lazy initialization pattern
        _cachedUser ??= LoadUser(id);
        return _cachedUser;
    }

    public void EnsureListInitialized()
    {
        // ✅ Ensure collection is initialized
        _items ??= new List<string>();
        _items.Add("item");
    }

    public void UpdateNameIfNull(User user)
    {
        // ✅ Set only if currently null
        user.MiddleName ??= "N/A";
    }

    // Before C# 8, you would write:
    public void OldWay()
    {
        if (_items == null)
        {
            _items = new List<string>();
        }

        // Or:
        _items = _items ?? new List<string>();
    }
}

Pattern Matching with Null

C# 9+ pattern matching enhancements for null checking.

Null Pattern Matching
csharp
public class PatternMatchingExamples
{
    public void IsPatterns()
    {
        object? obj = GetObject();

        // ✅ Check for null
        if (obj is null)
        {
            Console.WriteLine("Object is null");
        }

        // ✅ Check for not null
        if (obj is not null)
        {
            Console.WriteLine("Object is not null");
        }

        // ✅ Type pattern with null check
        if (obj is string s)
        {
            // s is not null here
            Console.WriteLine(s.ToUpper());
        }

        // ✅ Property pattern
        if (obj is User { Name: not null } user)
        {
            Console.WriteLine(user.Name);
        }
    }

    public string GetDescription(User? user) => user switch
    {
        null => "No user",
        { Name: null } => "User without name",
        { Name: var name } => $"User: {name}"
    };

    public void RecursivePatterns()
    {
        Order? order = GetOrder();

        // ✅ Complex pattern matching
        var status = order switch
        {
            null => "No order",
            { Customer: null } => "Order without customer",
            { Customer.Address: null } => "Customer without address",
            { Customer.Address.City: var city } => $"Shipping to {city}",
        };
    }
}

Migration Strategies

Gradually migrate existing code to nullable reference types.

Incremental Migration
csharp
// Step 1: Enable nullable in .csproj with warnings as errors
<PropertyGroup>
    <Nullable>enable</Nullable>
    <WarningsAsErrors>nullable</WarningsAsErrors>
</PropertyGroup>

// Step 2: Migrate file by file
#nullable enable

public class MigratedClass
{
    // Fix all warnings in this file
    public string Name { get; set; } = string.Empty;
    public string? Description { get; set; }
}

// Step 3: Use #nullable disable for legacy code
#nullable disable

public class LegacyClass
{
    // No nullable warnings here
    public string Name { get; set; }
}

#nullable restore
Migration Patterns
csharp
public class MigrationPatterns
{
    // Before: Everything nullable by default
    #nullable disable
    public string GetUserName(User user)
    {
        return user.Name;
    }
    #nullable restore

    // After: Explicit nullability
    #nullable enable
    public string GetUserNameNullable(User? user)
    {
        if (user == null)
        {
            throw new ArgumentNullException(nameof(user));
        }

        return user.Name ?? throw new InvalidOperationException("Name is required");
    }

    // Pattern: Make optional parameters explicit
    // Before
    #nullable disable
    public void ProcessData(string data, string format)
    {
        format = format ?? "json";
    }
    #nullable restore

    // After
    #nullable enable
    public void ProcessDataNullable(string data, string? format = null)
    {
        format ??= "json";
    }

    // Pattern: Use nullable return types
    // Before
    #nullable disable
    public User FindUser(int id)
    {
        return _repository.Find(id); // May return null
    }
    #nullable restore

    // After
    #nullable enable
    public User? FindUserNullable(int id)
    {
        return _repository.Find(id);
    }
}

Compiler Warnings and Strictness

Understanding and configuring nullable warning levels.

Warning Levels
csharp
// In .csproj
<PropertyGroup>
    <Nullable>enable</Nullable>

    <!-- Treat nullable warnings as errors -->
    <WarningsAsErrors>CS8600;CS8601;CS8602;CS8603;CS8604</WarningsAsErrors>

    <!-- Or treat all nullable warnings as errors -->
    <WarningsAsErrors>nullable</WarningsAsErrors>
</PropertyGroup>

// Common warnings:
// CS8600: Converting null literal or possible null value to non-nullable type
// CS8601: Possible null reference assignment
// CS8602: Dereference of a possibly null reference
// CS8603: Possible null reference return
// CS8604: Possible null reference argument

#nullable enable

public class WarningExamples
{
    // CS8618: Non-nullable property must contain non-null value when exiting constructor
    public string Name { get; set; } = string.Empty;

    // CS8603: Possible null reference return
    public string GetName(User? user)
    {
        return user?.Name ?? string.Empty; // Fix
    }

    // CS8602: Dereference of possibly null reference
    public int GetLength(string? value)
    {
        return value?.Length ?? 0; // Fix
    }

    // Suppress specific warning
    #pragma warning disable CS8602
    public void LegacyCode(string? value)
    {
        Console.WriteLine(value.Length); // Warning suppressed
    }
    #pragma warning restore CS8602
}

Nullable in Generic Constraints

Handling nullability in generic type parameters.

Generic Nullable Constraints
csharp
#nullable enable

public class GenericNullability
{
    // T? is nullable for both reference and value types
    public T? FindOrDefault<T>(int id)
    {
        var result = _repository.Find<T>(id);
        return result; // May be null
    }

    // where T : class - T is a reference type
    public T Create<T>(string name) where T : class, new()
    {
        var instance = new T();
        return instance; // Never null
    }

    // where T : class? - T is a nullable reference type
    public void Process<T>(T? value) where T : class
    {
        if (value == null)
        {
            return;
        }

        // value is not null here
        Console.WriteLine(value.ToString());
    }

    // where T : struct - T is a non-nullable value type
    public T GetValue<T>() where T : struct
    {
        return default; // Returns default value, never null
    }

    // where T : notnull - T cannot be nullable
    public void RequireNonNull<T>(T value) where T : notnull
    {
        // value is guaranteed not to be null
        Console.WriteLine(value.ToString());
    }
}
Nullable Generic Patterns
csharp
public class Repository<T> where T : class
{
    private readonly Dictionary<int, T> _cache = new();

    // Return nullable when not found
    public T? Find(int id)
    {
        _cache.TryGetValue(id, out var result);
        return result;
    }

    // Throw when not found
    public T Get(int id)
    {
        return _cache[id]; // Throws if not found
    }

    // Try pattern
    public bool TryGet(int id, [NotNullWhen(true)] out T? result)
    {
        return _cache.TryGetValue(id, out result);
    }
}

public class NullableGenericList<T>
{
    private readonly List<T> _items = new();

    // First or null
    public T? FirstOrDefault()
    {
        return _items.Count > 0 ? _items[0] : default;
    }

    // Find with predicate
    public T? Find(Predicate<T> predicate)
    {
        foreach (var item in _items)
        {
            if (predicate(item))
            {
                return item;
            }
        }
        return default;
    }
}

Best Practices

  1. Enable Nullable Globally: Use <Nullable>enable</Nullable> in .csproj
  2. Explicit Nullability: Make nullability intentions clear in APIs
  3. Validate at Boundaries: Check for null at public API boundaries
  4. Use Null-Conditional Operators: Prefer ?. over explicit null checks
  5. Avoid Null-Forgiving: Use ! sparingly and only when truly necessary
  6. Return Non-Nullable: Prefer non-nullable return types when possible
  7. Use Annotations: Apply [NotNull], [MaybeNull] etc. appropriately
  8. Constructor Initialization: Initialize non-nullable properties in constructors
  9. Throw on Invalid State: Throw exceptions for unexpected nulls
  10. Gradual Migration: Migrate file-by-file with #nullable directives
Show full SKILL.md (157 more words)Show less

Common Pitfalls

  1. Overusing !: Suppressing warnings instead of fixing root cause
  2. Not Initializing: Forgetting to initialize non-nullable properties
  3. Silent Failures: Not handling null cases in public APIs
  4. Mixing Contexts: Inconsistent nullable/disable throughout codebase
  5. Ignoring Warnings: Treating warnings as noise instead of issues
  6. Null Return Types: Returning null without nullable return type
  7. Unchecked Parameters: Not validating nullable parameters
  8. Generic Confusion: Misunderstanding T? in generic methods
  9. Legacy Assumptions: Assuming all references can be null
  10. False Confidence: Trusting ! operator without verification

When to Use

Use this skill when:

  • Writing null-safe C# code
  • Migrating to nullable reference types
  • Preventing NullReferenceExceptions
  • Designing clear APIs with explicit nullability
  • Working with optional values
  • Implementing defensive programming
  • Refactoring legacy code
  • Setting up new C# projects
  • Enforcing null safety at compile time
  • Working with generic nullable types

Resources

© sketch7, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/csharp-nullable-types of sketch7/FluentlyHttpClient.

Open the folder on GitHubat commit 397ee9b

Used in 1 other repository

We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in sketch7/FluentlyHttpClient, which our catalogue first saw on October 7, 2026.

Compare with similar skills

Csharp Nullable Types next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Csharp Nullable Types compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Csharp Nullable Types this skillsketch7/FluentlyHttpClient1211 repos~5.7kAutomated safety check: NotesMIT
Speckit ConstitutionWeihanLi/WeihanLi.Common24211 repos~2.1kAutomated safety check: PassApache-2.0
Issue Fixmono/SkiaSharp5.6k—~5.1kAutomated safety check: PassMIT
Analyzing .NET Performancedotnet/skills5.6k3 repos~3.1kAutomated safety check: PassMIT
Add Analyzerdotnet/roslynator3.5k—~1.3kAutomated safety check: PassCustom licence
GitVersion .NET DevelopmentGitTools/GitVersion3.1k—~1.7kAutomated safety check: PassMIT

Similar skills

  • Speckit Constitution

    WeihanLi/WeihanLi.Common

    Create or update the project constitution from interactive or provided principle inputs, ensuring all dependent templates stay in sync.

    242 GitHub starsUsed in 11 repos~2.1k tokens
    DevelopmentAuto-check passed
  • Issue Fix

    mono/SkiaSharp

    Fix bugs in SkiaSharp C bindings. An agent skill from mono/SkiaSharp.

    5.6k GitHub stars~5.1k tokensUpdated today
    DevelopmentAuto-check passed
  • Official

    Scans C# and .NET code for about 50 performance anti-patterns and reports prioritized findings with concrete fixes, at a scan depth you choose.

    5.6k GitHub starsUsed in 3 repos~3.1k tokens
    DevelopmentAuto-check passed
  • Add Analyzer

    dotnet/roslynator

    Official

    A skill your agent uses when adding a new RCS diagnostic in roslynator (RCS0 formatting, RCS1 general, RCS9 code-analysis), wiring roslynator EditorConfig options, or when docs say CHANGELOG.md…

    3.5k GitHub stars~1.3k tokensUpdated 3 days ago
    DevelopmentAuto-check passed
  • GitVersion .NET Development

    GitTools/GitVersion

    Gives repository-specific .NET guidance for GitVersion: build and test commands, central package management, project layout and coding conventions.

    3.1k GitHub stars~1.7k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Code Review

    dotnet/macios

    Official

    Review dotnet/macios PRs against established rules. An agent skill from dotnet/macios.

    2.9k GitHub stars~1.7k tokensUpdated today
    DevelopmentAuto-check passed

More from sketch7/FluentlyHttpClient

  • Csharp Async Patterns

    sketch7/FluentlyHttpClient

    A skill your agent uses when C async/await patterns including Task, ValueTask, async streams, and cancellation.

    121 GitHub starsUsed in 1 repo~5.9k tokens
    Auto-check: notes
  • Modern Csharp Coding Standards

    sketch7/FluentlyHttpClient

    Write modern, high-performance C code using records, pattern matching, value objects, async/await, Span<T/Memory<T, and best-practice API design patterns.

    121 GitHub starsUsed in 3 repos~2.7k tokens
    Auto-check passed
  • Dotnet 10 Csharp 14

    sketch7/FluentlyHttpClient

    A skill your agent uses when building .NET 10 or C 14 applications; when using minimal APIs, modular monolith patterns, or feature folders; when implementing HTTP resilience, Options pattern…

    121 GitHub stars~2.2k tokensUpdated 19 days ago
    Auto-check passed

Works with

Categories

Questions about Csharp Nullable Types

What does Csharp Nullable Types do?

A skill your agent uses when C nullable reference types, null safety patterns, and migration strategies. Csharp Nullable Types is an agent skill from sketch7/FluentlyHttpClient. Use when C nullable reference types, null safety patterns, and migration strategies.

When should I use Csharp Nullable Types?

Csharp Nullable Types fits situations like: C nullable reference types; null safety patterns; migration strategies; ensuring null safety in C code.

How do I install Csharp Nullable Types in Claude Code?

Run `npx skills add sketch7/FluentlyHttpClient --skill csharp-nullable-types -a claude-code`. Or copy the skill folder (.agents/skills/csharp-nullable-types in sketch7/FluentlyHttpClient) into .claude/skills/csharp-nullable-types in your project. Claude Code loads it when a task matches its description.

How do I install Csharp Nullable Types in Codex?

Run `npx skills add sketch7/FluentlyHttpClient --skill csharp-nullable-types -a codex`. Or copy the skill folder (.agents/skills/csharp-nullable-types in sketch7/FluentlyHttpClient) into .agents/skills/csharp-nullable-types in your project. Codex loads it when a task matches its description.

Can I use Csharp Nullable Types in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add sketch7/FluentlyHttpClient --skill csharp-nullable-types -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/csharp-nullable-types, .gemini/skills/csharp-nullable-types, .github/skills/csharp-nullable-types and .opencode/skills/csharp-nullable-types in your project.

What does Csharp Nullable Types need to run?

SKILL.md names no scripts, command-line tools or credentials: Csharp Nullable Types is instructions for the agent only. Its frontmatter pre-approves these tools: Bash, Read, Write, Edit.

Does Csharp Nullable Types access the network?

SKILL.md names 1 domain. As links in the text: learn.microsoft.com. This is read from the text; nothing was executed.

Is Csharp Nullable Types safe to install?

Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Csharp Nullable Types use?

Csharp Nullable Types is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Csharp Nullable Types use?

About 5.7k tokens (SKILL.md is roughly 23k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Csharp Nullable Types?

Skills that share tags, products or a category with Csharp Nullable Types: Speckit Constitution (WeihanLi/WeihanLi.Common, 242 stars), Issue Fix (mono/SkiaSharp, 5.6k stars), Analyzing .NET Performance (dotnet/skills, 5.6k stars) and Add Analyzer (dotnet/roslynator, 3.5k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Csharp Nullable Types?

sketch7 (a GitHub organization) maintains it in sketch7/FluentlyHttpClient, which has 121 GitHub stars. The repository holds 4 skills in this directory. The repository was last updated on September 18, 2026.

Source: sketch7/FluentlyHttpClient on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.