Skip to main content

Documentation Index

Fetch the complete documentation index at: https://ancplua.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Extension methods for object providing safe casting, type checking, and reflection utilities.

Safe Casting

As (Reference Types)

Safely cast with fluent syntax:
// Before: parentheses required for chaining
var method = (symbol as IMethodSymbol)?.Parameters;

// After: more readable chaining
var method = symbol.As<IMethodSymbol>()?.Parameters;

AsValue (Value Types)

Safely unbox value types:
object boxedInt = 42;
int? value = boxedInt.AsValue<int>();  // 42

object boxedString = "hello";
int? value2 = boxedString.AsValue<int>();  // null (not exception)

Type Checking with Casting

Is (Reference Types)

Combine type check and cast in one operation:
if (symbol.Is<IMethodSymbol>(out var method))
{
    // method is guaranteed non-null here
    ProcessMethod(method);
}

IsValue (Value Types)

Same pattern for value types:
if (constantValue.IsValue<int>(out var intValue))
{
    ProcessInt(intValue);
}

CastTo (Throwing Cast)

When you’re certain of the type and want a clear exception on failure:
// Throws InvalidCastException with clear message if wrong type
var method = symbol.CastTo<IMethodSymbol>();

Reflection Helpers

Safe property access without catching exceptions.

HasProperty

Check if a property exists:
if (obj.HasProperty("Name"))
{
    var name = obj.TryGetPropertyValue<string>("Name");
}

TryGetPropertyValue

Get property values safely:
// With default value
var name = obj.TryGetPropertyValue<string>("Name", "Unknown");
var id = obj.TryGetPropertyValue<int>("Id", -1);
var isActive = obj.TryGetPropertyValue<bool>("IsActive", false);

// Try-pattern
if (obj.TryGetPropertyValue<string>("Name", out var name))
{
    Console.WriteLine(name);
}
Returns default when:
  • Object is null
  • Property doesn’t exist
  • Property value is null
  • Property value cannot be cast to the requested type

Equality and Comparison

EqualsTo

Null-safe equality comparison:
if (value1.EqualsTo(value2))
{
    // Values are equal (both null counts as equal)
}

IsOneOf / IsNotOneOf

Check if a value is one of several options:
if (status.IsOneOf(Status.Active, Status.Pending))
{
    // Process active or pending status
}

if (status.IsNotOneOf(Status.Deleted, Status.Archived))
{
    // Process non-deleted, non-archived items
}

// Works with any type
if (extension.IsOneOf(".cs", ".vb", ".fs"))
{
    // It's a .NET source file
}

Null Utilities

IfNotNull (Action)

Execute an action if not null:
// Before
if (logger != null)
{
    logger.Log(message);
}

// After
logger.IfNotNull(l => l.Log(message));

IfNotNull (Transform)

Transform if not null, return default otherwise:
// Before
var length = str != null ? str.Length : 0;

// After
var length = str.IfNotNull(s => s.Length) ?? 0;

// Complex transformations
var info = user.IfNotNull(u => new { u.Name, u.Email });

IfNotNull with Default

Transform with explicit default:
var displayName = user.IfNotNull(u => u.Name, "Guest");
var itemCount = list.IfNotNull(l => l.Count, 0);

Examples

Processing Roslyn Symbols

public void ProcessSymbol(ISymbol symbol)
{
    // Pattern: check type and cast
    if (symbol.Is<IMethodSymbol>(out var method))
    {
        if (method.IsAsync)
        {
            ProcessAsyncMethod(method);
        }
    }
    else if (symbol.Is<IPropertySymbol>(out var property))
    {
        if (property.IsReadOnly)
        {
            ProcessReadOnlyProperty(property);
        }
    }
}

Duck Typing with Reflection

public T? GetDuckTypedValue<T>(object obj)
{
    // Safely access properties on unknown types
    if (obj.HasProperty("Value"))
    {
        return obj.TryGetPropertyValue<T>("Value");
    }

    // Try alternative property name
    if (obj.HasProperty("Data"))
    {
        return obj.TryGetPropertyValue<T>("Data");
    }

    return default;
}

State Machine with IsOneOf

public bool CanTransitionTo(OrderState newState)
{
    return _currentState switch
    {
        OrderState.Draft when newState.IsOneOf(OrderState.Pending, OrderState.Cancelled) => true,
        OrderState.Pending when newState.IsOneOf(OrderState.Processing, OrderState.Cancelled) => true,
        OrderState.Processing when newState.IsOneOf(OrderState.Shipped, OrderState.Cancelled) => true,
        OrderState.Shipped when newState == OrderState.Delivered => true,
        _ => false
    };
}

Optional Processing

public string BuildGreeting(User? user)
{
    return user
        .IfNotNull(u => u.PreferredName)
        .IfNotNull(name => $"Hello, {name}!")
        ?? "Welcome, guest!";
}

API Reference

Safe Casting

MethodDescription
As<T>()Cast to reference type, returns null on failure
AsValue<T>()Unbox to value type, returns null on failure
Is<T>(out result)Type check + cast for reference types
IsValue<T>(out result)Type check + unbox for value types
CastTo<T>()Cast or throw InvalidCastException

Reflection

MethodDescription
HasProperty(name)Check if public instance property exists
TryGetPropertyValue<T>(name, default)Get property value or default
TryGetPropertyValue<T>(name, out value)Try-pattern property access

Equality

MethodDescription
EqualsTo<T>(other)Null-safe equality comparison
IsOneOf<T>(values)Check if equals any of the values
IsNotOneOf<T>(values)Check if not equal to any of the values

Null Utilities

MethodDescription
IfNotNull<T>(action)Execute action if not null
IfNotNull<T, TResult>(selector)Transform if not null, return default otherwise
IfNotNull<T, TResult>(selector, default)Transform if not null, return specified default otherwise
The Is<T> and IsValue<T> methods are particularly useful in switch statements or when you need both the type check and the cast result in one operation.