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));
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
| Method | Description |
|---|
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
| Method | Description |
|---|
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
| Method | Description |
|---|
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
| Method | Description |
|---|
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.