This project provides functionality to automatically implement interfaces.
This project contains a source generator that automatically implements interface members in classes implementing the interfaces.
The goal is to provide a workaround for C# not supporting multiple inheritance for some basic use cases.
Install the NuGet package Basilisque.AutoImplementer.CodeAnalysis.Fasteroid.
Installing the package will add the source generator to your project.
Now you're ready to start implementing your interfaces automatically.
-
Automatic implementation of interfaces on classes
-
Classes have to be marked with the
[AutoImplementInterfaces]attribute- Then all interfaces marked with the
[AutoImplementInterface]attribute will be implemented[AutoImplementInterface] public interface ITitle { string Title { get; set; } } public interface ISummary { string Summary { get; set; } } [AutoImplementInterfaces] public partial class Book : ITitle, ISummary { /* will have the property 'Title' only. 'ISummary' is not marked with an attribute */ }
- By specifying the interfaces explicitly within the attribute on the class, the interfaces dont't have to be marked
([AutoImplementInterfaces<IInterface>()]or[AutoImplementInterfaces(typeof(IInterface))])public interface ITitle { string Title { get; set; } } public interface ISummary { string Summary { get; set; } } [AutoImplementInterfaces<ITitle, ISummary>()] //[AutoImplementInterfaces(typeof(ITitle), typeof(ISummary))] <- alternative syntax public partial class Book : ITitle, ISummary { /* will have the properties 'Title' and 'Summary' */ }
- Then all interfaces marked with the
-
When the interfaces are explicitly stated, they don't have to be stated as base type a second time. This is valid:
public interface ITitle { string Title { get; set; } } [AutoImplementInterfaces<ITitle>()] //[AutoImplementInterfaces(typeof(ITitle))] <- alternative syntax public partial class Book // ': ITitle' <- this is optional because 'ITitle' was specified in the attribute { }
- By default, all non-nullable properties are implemented with the 'required' modifier
public interface IBook { string Title { get; set; } // required DateOnly? PublishDate { get; set; } // not required string Publisher { get; set; } // required }
- This can be disabled by setting the 'Strict' property to 'false' in the
[AutoImplementInterface]attribute, but it's not recommended.[AutoImplementInterface(Strict = false)] public interface IMovie { [Required] string Title { get; set; } // required [AutoImplement(AsRequired = true)] // required TimeSpan Runtime { get; set; } string Summary { get; set; } // not required (unsafe!) }
- Properties can also be skipped. Then they have to be implemented manually.
public interface IPublish { DateOnly PublishDate { get; set; } [AutoImplement(Implement = false)] // skips the 'Publisher' property string? Publisher { get; set; } }
Create the interfaces:
[AutoImplementInterface]
public interface ITitle
{
[Required] string Title { get; set; }
}
public interface IDetails
{
byte[]? Image { get; set; }
string Summary { get; set; }
}Create some classes implementing the interfaces:
[AutoImplementInterfaces()] // <- no interfaces were stated explicitly. 'ITitle' will be implemented because it is marked with the 'AutoImplementInterface' attribute
public partial class Book : ITitle, IDetails
{ /* will have the properties Title only */ }
[AutoImplementInterfaces<IDetails>()] // <- 'IDetails' was stated explicitly; only this interface will be implemented
public partial class Movie : ITitle, IDetails
{ /* will have the properties Image and Summary */ }
[AutoImplementInterfaces<IDetails>()] // <- will implement 'IDetails'
[AutoImplementInterfaces()] // <- will find 'ITitle' because it is marked with the 'AutoImplementInterface' attribute
public partial class Game : ITitle, IDetails
{ /* will have the properties Title, Image and Summary */ }
[AutoImplementInterfaces(typeof(ITitle), typeof(IDetails))]
public partial class Event
{ /* will have the properties Title, Image and Summary */ }The source generator now adds the members to the corresponding classes without you having to do this on your own every time.
For details see the wiki.
The Basilisque framework (including this repository) is licensed under the Apache License, Version 2.0.