A .NET library implementing the Liskov/Wing Substitution Principle for type variance checking (including generic typeParameters constraints validation). Provides additional variance checking capabilities when working with GenericTypeDefinitions.
$ dotnet add package TypeLogic.LiskovWingSubstitutionA .NET library implementing the Liskov/Wing Substitution Principle for type variance checking (including generic typeParameters constraints validation).
This project emerged from previous R&D tests dealing with .NET generics: I needed an additional simple way to verify type variance against GenericTypeDefinition, complementing .NET's built-in type system capabilities.
What started as a proof-of-concept to simplify variance checking turned into a full-fledged library that extends .NET's type system that you may find educational or even practicalin some cases. The implementation is based from Barbara Liskov's and Jeannette Wing's work on behavioral subtyping, providing additional variance checking capabilities when working with GenericTypeDefinitions (especially in cases where non-generic Type inheritance is absent, as illustrated in the examples).
The package can be installed via NuGet:
dotnet add package TypeLogic.LiskovWingSubstitution
using TypeLogic.LiskovWingSubstitution;
// Check if List<string> is variant of IEnumerable<object>
bool isVariant = typeof(List<string>).IsSubtypeOf(typeof(IEnumerable<object>));
// Check with runtime type information
bool isVariantWithType = typeof(List<string>).IsSubtypeOf(typeof(IEnumerable<object>), out Type runtimeType);
using TypeLogic.LiskovWingSubstitution;
List<string> instance = new List<string>();
// Check with type parameter
bool isInstanceOfType = instance.IsInstanceOf(typeof(IEnumerable<object>), out var runtimeType);
// runtimeType should be IEnumerable<string>
using TypeLogic.LiskovWingSubstitution;
string instance = "this is a string";
// Check with against generic type with the corresponding runtimeType
bool isInstanceOfType = instance.IsInstanceOf(typeof(IEquatable<>), out var runtimeType);
// runtimeType should be IEquatable<string>
using TypeLogic.LiskovWingSubstitution;
// Check if List<T> is variant of IEnumerable<>
bool isGenericVariant = typeof(List<int>).IsSubtypeOf(typeof(IEnumerable<>));
// Convert instance based on generic definition
string instance = "test";
var converted = instance.ConvertAs(typeof(IEnumerable<>)); // Converts to IEnumerable<char>
The library implements comprehensive type variance checking:
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
tools/compare-benchmarks.ps1 when relevant).