Durian.InterfaceTargets, similar to how the System.AttributeUsageAttribute works, allows to specify member kinds an interface can be implemented by.
Packages that are part of the InterfaceTargets module:
InterfaceTargets provides 2 types:
To start using InterfaceTargets, reference either the Durian.InterfaceTargets or Durian package.
Note: Like with other Durian modules, the target project must reference the Durian.Core package as well.
The premise of this package is fairly straight-forward and recognizable. Similar to how System.AttributeUsageAttribute works, the Durian.InterfaceTargetsAttribute allows to specify what kind of members the target interface can be implemented by.
using Durian;
[InterfaceTargets(InterfaceTargets.Class)]
public interface ITest
{
}
// Success!
// ITest can be implemented, because ClassTest is a class.
public class ClassTest : ITest
{
}
// Error!
// ITest cannot be implemented, because StructTest is a struct, and ITest is valid only for classes.
public struct StructTest : ITest
{
}
It is possible to specify more than one member kind.
using Durian;
[InterfaceTargets(InterfaceTargets.Class | InterfaceTargets.Struct)]
public interface ITest
{
}
// Success!
// ITest can be implemented, because ClassTest is a class.
public class ClassTest : ITest
{
}
// Success!
// ITest can be implemented, because StructTest is a struct.
public struct StructTest : ITest
{
}
// Error!
// ITest cannot be implemented, because IInterfaceTest is an interface, and ITest is valid only for classes or structs.
public interface IInterfaceTest : ITest
{
}
InterfaceTargets works only on syntax level - it is possible to implement an interface for a member of forbidden kind through reflection.
For cases when such behavior is the only intended way, InterfaceTargets.ReflectionOnly can be applied.
using Durian;
[InterfaceTargets(InterfaceTargets.ReflectionOnly)]
public interface ITest
{
}
// Error!
// ITest can be implemented in code.
public class ClassTest : ITest
{
}
// Error!
// ITest can be implemented in code.
public struct StructTest : ITest
{
}
The possible values of the Durian.InterfaceTargets enum are:
- None - Interface cannot be implemented in code.
- ReflectionOnly - Interface can only be implemented through reflection; the same as None.
- Class - Interface can only be implemented by classes.
- Interface - Interface can only be implemented by other interfaces.
- Struct - Interface can only be implemented by structs.
- RecordClass - Interface can only be implemented by record classes.
- RecordStruct - Interface can only be implemented by record structs.
- All - Interface can be applied to all kinds of members; same as not specifying the Durian.InterfaceTargetsAttribute at all.
(Written by Piotr Stenke)