About • How To Use • Download • Contributors • Versioning • Credits • Related • License
Reflectify offers a bunch of extension methods to provide information such as the properties or fields a type exposes and metadata about those members, and many other details about classes, records and interfaces. It supports all major .NET versions and even understands explicitly implemented properties or properties coming from default interface implementations, a C# 8 feature.
Nothing really, but it offers that functionality through a content-only NuGet package that relies on C# 12. In other words, you can use this package in your own packages, without the need to tie yourself to the Reflectify package. Oh, and it's used by an open-source project with over 400 million downloads.
My name is Dennis Doomen and I'm a Microsoft MVP and Principal Consultant at Aviva Solutions with 28 years of experience under my belt. As a software architect and/or lead developer, I specialize in designing full-stack enterprise solutions based on .NET as well as providing coaching on all aspects of designing, building, deploying and maintaining software systems. I'm the author of Fluent Assertions, a popular .NET assertion library, Liquid Projections, a set of libraries for building Event Sourcing projections and I've been maintaining coding guidelines for C# since 2001.
Contact me through Email, BlueSky, Twitter/X or Mastadon
Simple, to get the properties of a type, add the Reflectify NuGet package to a project that targets at least C# 12 and use
using Reflectify;
var properties = typeof(SuperClass).GetProperties(
MemberKind.Public | MemberKind.ExplicitlyImplemented | MemberKind.DefaultInterfaceProperties);You can take any of the options Public, Internal, Static, ExplictlyImplemented and DefaultInterfaceProperties.
If you need the fields, use GetFields (which obviously cannot be explicitly implemented, nor be part of interfaces),
and if you need the members, use GetMembers. You can also request individual members by name, like
GetProperty("Name", MemberKind.Public) or GetField("Name", MemberKind.Internal).
To get more metadata from a PropertyInfo, you can use extensions methods like:
IsExplictlyImplementedIsIndexerHasAttributeandHasAttributeInHierarchyIsPublic,IsInternalorIsAbstractto check either the getter or setters matches the criteriaIsInitOnlyto detect C# 9 init-only properties,IsRequiredto detect the C# 11requiredmodifier, andIsWritableto see if a property can be assigned outside of an object initializer or constructorGetNullabilityandIsNullableReferenceto determine the nullable reference type annotation of the property
Similarly, you can find indexers using FindIndexers, conversion operators through FindImplicitConversionOperators
and FindExplicitConversionOperators, and methods via FindMethod, FindParameterlessMethod and HasMethod.
For a FieldInfo, you can use GetNullability and IsNullableReference in the same way as for PropertyInfo.
For ParameterInfo, you can use:
HasAttributeandHasAttributeInHierarchyto check whether a parameter is decorated with a specific attribute, with an optional predicate to filter on attribute properties.GetNullabilityandIsNullableReferenceto determine the nullable reference type annotation of the parameter.
Other extension methods act on Type directly and include:
IsDerivedFromOpenGenericandGetClosedGenericInterfaces- Various
HasAttribute,HasAttributeInHierarchyandGetMatchingAttributesoverloads, with and without additional filtering. OverridesEqualsto determine if a type implements value semanticsIsSameOrInheritsto see if a type is the same as or derives from another (open-generic) typeIsCompilerGeneratedandHasFriendlyNameto see if a type is (partially) generated by the compiler, like records, tuples, etc.IsAnonymous,IsTuple,IsRecord,IsRecordClass,IsRecordStruct,IsKeyValuePair,IsDelegate,IsStruct,IsRefStructto find these types.IsReadOnlyStructto detect readonly structs, andIsFileLocalto detect C# 11file-local types.GetNonGenericNameto get the name of a type without the generic backtick and number of parameters.GetFriendlyNameandGetFullFriendlyNameto render a type the way a C# developer would write it, e.g.Dictionary<string, List<int>>orint?, optionally including the full namespace.IsNullableto check whether a type is a constructedNullable<T>.IsEnumerableandGetElementTypeOfEnumerableto check whether a type is an enumerable (excludingstring) and, if so, get its element type.IsDictionaryandTryGetDictionaryTypesto check whether a type is a dictionary and, if so, get its key and value types.IsAwaitableto check whether a type can be awaited usingawait, based on the compiler's awaitable pattern.IsTaskLiketo check whether a type isTask,Task<T>,ValueTask, orValueTask<T>.IsNumericto check whether a type is one of the numeric primitive types (includingdecimal).IsPrimitiveOrStringto check whether a type is a CLR primitive orstring.
Additionally, Reflectify offers some helpers such as
NullableOrActualTypeto get the actual type of a nullable type or the type itself if it's not nullable.
GetNullability returns a Nullability enum (Unknown, NotNull or Nullable) that reflects the compiler-emitted
nullable reference type metadata for reference types, and treats value types consistently with NullableOrActualType
(e.g. int is NotNull, int? is Nullable). IsNullableReference is a convenience shortcut for
GetNullability() == Nullability.Nullable. On .NET 6 and later this is backed by NullabilityInfoContext; on older
targets it's determined by reading the compiler's NullableAttribute/NullableContextAttribute metadata directly.
This library is available as a NuGet package on https://nuget.org. To install it, use the following command-line:
dotnet add package Reflectify
Your contributions are always welcome! Please have a look at the contribution guidelines first.
(Made with contrib.rocks)
This library uses Semantic Versioning to give meaning to the version numbers. For the versions available, see the tags on this repository.
This library wouldn't have been possible without the following tools, packages and companies:
- Nuke - Smart automation for DevOps teams and CI/CD pipelines
- Rider - The world's most loved .NET and game dev IDE
- xUnit - Community-focused unit testing tool for .NET.
- Coverlet - Cross platform code coverage for .NET
- Polysharp - Generated, source-only polyfills for C# language features
- GitVersion - From git log to SemVer in no time
- ReportGenerator - Powerful code coverage visualization
- My Blog
- Mockly - Fluent HTTP mocking for .NET like it should have been done
- Pathy - Fluently building and using file and directory paths without binary dependencies
- FluentAssertions - Extension methods to fluently assert the outcome of .NET tests
- C# Coding Guidelines - Forkable coding guidelines for all C# versions
This project is licensed under the MIT License - see the LICENSE.md file for details.