The following code snippets are simplified to demonstrate the context! The actual interfaces and classes are POCOs having additional properties. The types are part of library I am working on, the interfaces are public API, the classes internal API.
I have:
an interface IValue
public interface IValue { Int32 Value { get; } }
2 different IConfigurableValue interfaces (2 separate git branches) which extend
IValue
, see further onpublic interface IConfigurableValue : IValue { void CopyFrom(IValue source); // is always part of the interface }
an implementation AutoGeneratedValue
internal class AutoGeneratedValue : IConfigurableValue { public Int32 Value { get; set; } public void CopyFrom(IValue source) { Value = source.Value; } }
code which needs to access the getter only (via
IValue
) and code which requires aIConfigurableValue
(no compile-time known implementation)External users of the library can implement
IValue
andIConfigurableValue
on their own. Part of my library code creates an instance ofAutoGeneratedValue
. If the user provides a customIConfigurableValue
implementation myAutoGeneratedValue
is passed to it, the user decides if to ignore it or not. Another API part accepts an instance ofIValue
and does something. It only needs to read the instance properties. This part of the API can be invoked without ever requiring anyIConfigurableValue
instances.
My goal for the library is a) to offer methods requiring an IValue
instance and b) methods to auto-generated IValue
instances or populate user-provided IConfigurableValue
instances which can be used for part a.
I currently have 2 branches with the following IConfigurableValue
definitions:
IConfigurableValue
will extend a separate IValueConfiguration as well asIValue
public interface IConfigurableValue : IValue, IValueConfiguration { void CopyFrom(IValue source); } public interface IValueConfiguration { Int32 Value { set; } }
and a
IConfigurableValue
which defines the setter itself, no additional interfacepublic interface IConfigurableValue : IValue { new Int32 Value { set; } void CopyFrom(IValue source); }
With both options I need to cast IConfigurableValue
to IValue
to access the getter in part b of my library.
With option no. 1 I need to cast IConfigurableValue
to IValueConfiguration
to access the setter.
Option no. 2 denies me the usage via a setter-only interface because any IConfigurableValue
is an IValue
,
with no. 1 I could use the IValueConfiguration
if I need it. -- This is no actual requirement of my API but I don't know the future demands for the API.
Is there another option to achieve my goal and which option should be preferred?
IConfigurableValue : IValue { Int32 Value { get; set; } }
? Does that compile?get
via both interfaces. Example:public class Sample : IConfigurableValue { Int32 IConfigurableValue.Value { get; set; } Int32 IValue.Value { get; } }
IConfigurableValue
needs to extendIValue
? You could just have them as two different interfaces implemented by the same class