Consider the following interface
public interface ICustomData
{
String CustomData { set; get; }
}
According to MSDN documentation, interfaces members are automatically public.
Lets say I now want to implement my interface:
public class CustomDataHandler : ICustomData
{
}
This would break at compile time, telling me that I have not implemented "CustomData"
This on the otherhand would work:
public class CustomDataHandler : ICustomData
{
public String CustomData { set; get; }
}
My question is: If the member of the interface is automatically public, why MUST I declare the implementation in the class? If the interface declaration is syntactically identical to the class declaration, why can the compiler not infer this automatically from my interface?
EDIT:
My reason for asking. Imagine a scenario where you are building data models, entities etc. I might code some interfaces to these models like so:
public interface IUserAccount
{
Guid Identity { set; get; }
String FirstName { set; get; }
String LastName { set; get; }
String EmailAddress { set; get; }
String Password { set; get; }
}
public interface IUserDataEntry
{
Guid DataIdentity { set; get; }
String DataName { set; get; }
String Data { set; get; }
}
It would be far simpler to construct the models like so:
public class UserAccount : IUserAccount
{
}
public class UserDataEntry : IUserDataEntry
{
}
public class Combined : IUserAccount, IUserDataEntry
{
}
An interface is not there to provide an implementation, it is there to define a contract. This then allows for different implementations to be built which implement it.
They may be syntactically identical, but they mean different things (i.e. they are not semantically identical).
In the interface, the syntax means that an implementing class must expose such a property, with get and set accessors implemented as it sees fit (either explicitly or implicitly). An interface merely defines the outward behaviour that a class must provide; it does not provide any implementation of that behaviour.
In the class, the syntax is an "auto-property", an implementation of the property defined by the interface, and the get and set accessors are implicitly converted into full implementations with a backing field. It looks something like this when it's compiled:
public class CustomDataHandler : ICustomData
{
private string customData;
public string CustomData
{
get
{
return customData;
}
set
{
customData = value;
}
}
}
You are implicitly implementing the interface. In this instance the method signatures of the class must match those of the interface (including accessibility). Ensuring that the methods are marked as public ensures that there are no surprises when looking at the class, for instance:
public class CustomDataHandler : ICustomData
{
String CustomData {get; set}
String PrivateCustomData {get;set;}
}
Even though both properties are declared the same, the CustomData property would be public by virtue of it being declared on the interface even though the declaration looks identical to that of PrivateCustomData. This would be inconsistent and lead to harder to maintain code.
If you do not wish to set the access modifier, you could explicitly implement the interface:
public class CustomDataHandler : ICustomData
{
String ICustomData.CustomData { set; get; }
}
The interface declaration is only specifying the behaviour which the interface defines. In your case, this is a property called CustomData which has a get and set (it is a read/write property) which is of type string.
The class which implements the interface needs to do exactly that - to specify the implementation.
Now in your case, you are using auto implemented properties { get; set; } which looks the same as the interface declaration, however you could also have a backing field and behaviour in your get or set methods.
Here's an example where the CustomData property is private in a derived class:
public class CustomDataHandler : ICustomData
{
private string CustomData { set; get; }
string ICustomData.CustomData { get; set; }
}
But this code compiles, because there is also an explicit implementation of the property.
So, the public modifier is not redundant in this case.
You must explicitly implement it because... You are not limited to implementing it that way. You could use a field, or do something else in your method. An interface is only a method contract that guaranty that this method exist.
public class CustomDataHandler : ICustomData
{
public String CustomData
{
get { return "None of your business!"; }
set { } // Decide to do nothing
}
}
The interface only guaranty this method will exist. Not what you're gonna do with it.
EDIT: As for your edit of your question, you probably seek to have a parent class instead of an interface if you want to implement the method only once for a collection of classes. However, while you can combine interface, you cannot combine parent classes. But, you can add interface at different point of a classes hierarchy.
Related
I'm trying to get a simple set of interfaces to be nested so I can enforce some members on derived classes.
public enum Category { Mental, Physical, Technical }
interface IAbilities
{
List<IAbility> Abilities { get; set; }
}
interface IAbility
{
Category Category { get; }
int Value { get; set; }
string Descritpion { get; set; }
}
public class MentalAbilities : IAbilities
{
// This is what I want so that "Abilities" is accessible
public List<MentalAbility> Abilities { get; set; }
// This is what Intellisense generates, cannot be set to public
//List<IAbility> IAbilities.Abilities { get; set; }
}
public class MentalAbility : IAbility
{
public Category Category { get; } category
public int Value { get; set; }
public string Descritpion { get; set; }
}
Of course the Intellisense generated bit compiles, but "Abilities" is not accessible from a class instance because it can't be set to public.
The bit I want tells me `'MentalAbilities' does not implement interface member 'IAbilities.Abilities'. 'MentalAbilities.Abilities' cannot implement 'IAbilities.Abilities' because it does not have the matching return type of List<IAbility>.
I don't understand since "MentalAbility" is derived from the "IAbility" interface so that should fulfill the contract.
(I'm skipping over the "x is less accessible than y" error because you already worked out you can make your interfaces public - sure you can appreciate how anything has to be at least as accessible as it's use)
Re your "does not implement" error:
I understand your problem, but you've kinda got it upside down
I see that you want to ensure, in your MentalAbilities.Abilities list, someone only puts MentalAbility objects.. and they implement IAbility so it should satisfy the "object is a IAbilities and has a list which contains only things that implement IAbility" rules, right?
Alas, no. This the pretty much the opposite of what inheritance or interface implementation is for.
The idea behind inheritance is that you can say "this thing can be any type at all as long as it has these common aspects and I will treat it in the common way". By declaring such that List<IAbility> you're saying "objects in this list just have to implement IAbility and then I'll be able to deal with them" - it could be a MentalAbility, or a PhysicalAbility - doesn't matter
You cannot then constrain the list to only containing MentalAbility via the inheritance/implements mechanism, nor should you because it's opposite of what it is for- going from "I can deal with anything so long as it implements X" to "I will only deal with something if it is, or is a subtype of, Y" is the opposite of what was claimed earlier. You're saying that MentalAbilities can only deal with the list contents if they're MentalAbility, when you earlier said it could deal with anything that was an IAbility
If you want to enforce that MentalAbilities only contains MentalAbility you'll have to declare it as List<IAbility> and look at the type of the IAbility you're given in the set and refuse to add it if if it's not a MentalAbility, but if other developers use your code they will be very confused - "what? It says I'm allowed to use anything that implements IAbility, and my TigerAbility does just that.. why am I getting an exception that it must be a MentalAbility? Why did this developer even use a List(IAbility) if I'm not allowed to sling any IAbility I like into it?" - it's also no longer a compile time thing, but a runtime one and that's a big risk
I think you need to decide if you're going to be able to treat these things in a generic way i.e. can your AbilitiesProcessor implement IAbilities and have a list of IAbility and process them regardless of actual type, or not. If it can't, and you're going to have a MentalAbilities class that can only deal with MentalAbility that's fine, and it can have a List<MentalAbility> all it wants, fellow developers won't mistakenly put a TigerAbility into it, but it won't implement the IAbilities interface
I'm trying to get a simple set of interfaces to be nested so I can enforce some members on derived classes.
Your main issue here is that defined the two interfaces as private by default. That's what is preventing you from creating public List<IAbility> Abilities { get; set; } inside MentalAbilities.
Actually, the property public List<MentalAbility> Abilities { get; set; } is also preventing you as you can't have a property of the same name defined twice.
The big question here would be what would be the point of allowing MentalAbilities the ability to set a List<IAbility> since that would mean setting any type of ability.
Ideally MentalAbilities should only have a single list of MentalAbility that it contains - and it should only be read-only. In fact, most of your interfaces should be read-only.
Here's what you should do:
Start with these interfaces:
public interface IAbilities<A> where A : IAbility
{
List<A> Abilities { get; }
}
public interface IAbility
{
Category Category { get; }
int Value { get; }
string Description { get; }
}
Notice the IAbilities<A> interface uses a generic type A that you can fill in later.
Next, let's set up some base classes that simplify the implementation of each specific class.
public abstract class AbilitiesBase<A> : IAbilities<A> where A : IAbility
{
public List<A> Abilities { get; protected set; }
}
public abstract class AbilityBase : IAbility
{
public abstract Category Category { get; }
public abstract int Value { get; }
public abstract string Description { get; }
}
Now the final classes are simple:
public class MentalAbilities : AbilitiesBase<MentalAbility> { }
public class MentalAbility : AbilityBase
{
public override Category Category => Category.Mental;
public override int Value => 42;
public override string Description => "Mental!";
}
There's nothing to implement in MentalAbilities - the base class took care of that - but it does have a List<MentalAbility> Abilities { get; } property.
MentalAbility is also neatly set up to enforce you to override the properties.
Now, if you actually wanted still have a List<IAbility> Abilities { get; } property then there's an easy way to do that by writing these two interfaces:
public interface IAbilities
{
List<IAbility> Abilities { get; }
}
public interface IAbilities<A> : IAbilities where A : IAbility
{
new List<A> Abilities { get; }
}
This forces a change to AbilitiesBase like this:
public abstract class AbilitiesBase<A> : IAbilities<A> where A : IAbility
{
public List<A> Abilities { get; protected set; }
List<IAbility> IAbilities.Abilities => this.Abilities.Cast<IAbility>().ToList();
}
The List<IAbility> IAbilities.Abilities property generates a copy of the public List<A> Abilities { get; protected set; } property, but that's what you want to prevent anyone adding the wrong type of ability to the original list.
Personally, I would go with this instead:
public interface IAbilities
{
IEnumerable<IAbility> Abilities { get; }
}
public interface IAbilities<A> : IAbilities where A : IAbility
{
new List<A> Abilities { get; }
}
public abstract class AbilitiesBase<A> : IAbilities<A> where A : IAbility
{
public List<A> Abilities { get; protected set; }
IEnumerable<IAbility> IAbilities.Abilities => this.Abilities.Cast<IAbility>();
}
What you are stuck with is called implicit and explicit implementation of interfaces in C#. If you define your class member like this:
public List<MentalAbility> Abilities { get; set; }
you are implementing IAbilities implicitly and you need to write public with it. If you define your class member as
List<IAbility> IAbilities.Abilities { get; set; }
you have implemented IAbilities explicitly, in which case it can be private.
While we are here, I see no point in defining an interface IAbilities. You should simply use IEnumerable<IAbility> anywhere you want to use IAbilities, which is literally providing no value in your code.
Why am I getting this error and how can I work around it when I CAN'T change the interfaces... (You can copy/paste the code into an empty CS file)
namespace ClassLibrary1
{
public interface IEntity
{
}
public interface IEntitySet<T>
{
}
public class Entity : IEntity
{
}
public class EntitySet<T> : IEntitySet<T>
{
}
public interface IImplementer
{
IEntitySet<IEntity> Set { get; set; }
}
public class Implementer : IImplementer
{
// Error 'ClassLibrary1.Implementer' does not implement interface member 'ClassLibrary1.IImplementer.Set'.
// 'ClassLibrary1.Implementer.Set' cannot implement 'ClassLibrary1.IImplementer.Set'
// because it does not have the matching return type of 'ClassLibrary1.IEntitySet<ClassLibrary1.IEntity>'.
public EntitySet<Entity> Set { get; set; }
}
}
Indeed, your Set method is meant to have a return type of IEntitySet<IEntity>, but you've tried to declare the implementation using EntitySet<Entity>. Two problems there:
IEntitySet isn't EntitySet
IEntity isn't Entity
The implementation signature has to match the interface exactly.
You should probably make IImplementer generic, like this:
public interface IImplementer<T> where T : IEntity
{
IEntitySet<T> Set { get; set; }
}
At that point, you can have:
public class Implementer : IImplementer<Entity>
{
public IEntitySet<Entity> Set { get; set; }
}
You can then write:
var implementer = new Implementer();
implementer.Set = new EntitySet<Entity>();
Is that what you want? If you really need to force Implementer to use EntitySet rather than just any IEntitySet, then you're probably coupling the two ideas too tightly.
You are getting this exception because IImplementer requires an IEntitySet<IEntity> Set property, but your Implementer class is returning an EntitySet<Entity>. EntitySet can be cast to IEntitySet, but IEntitySet cannot be cast to EntitySet, and so the interface implementation fails because you do not satisfy the interface.
Just change public EntitySet<Entity> Set {get; set;} to public IEntitySet<IEntity> Set {get; set;} on your Implementer class.
This is class design question.
I have main abstract class
public abstract class AbstractBlockRule
{
public long Id{get;set;}
public abstract List<IRestriction> Restrictions {get;};
}
public interface IRestriction{}
public interface IRestriction<T>:IRestriction where T:struct
{
T Limit {get;}
}
public TimeRestriction:IRestriction<TimeSpan>
{
public TimeSpan Limit{get;set;}
}
public AgeRestriction:IRestriction<int>
{
public int Limit{get;set;}
}
public class BlockRule:AbstractBlockRule
{
public virtual List<IRestriction> Restrictions {get;set;}
}
BlockRule rule=new BlockRule();
TimeRestriction t=new TimeRestriction();
AgeRestriction a=new AgeRestriction();
rule.Restrictions.Add(t);
rule.Restrictions.Add(a);
I have to use non-generic Interface IRestriction just to avoid specifying generic type T in main abstract class. I'm very new to generics. Can some one let me know how to better design this thing?
Your approach is typical (for example, IEnumerable<T> implements IEnumerable like this). If you want to provide maximum utility to consumers of your code, it would be nice to provide a non-generic accessor on the non-generic interface, then hide it in the generic implementation. For example:
public abstract class AbstractBlockRule
{
public long Id{get;set;}
public abstract List<IRestriction> Restrictions { get; set; }
}
public interface IRestriction
{
object Limit { get; }
}
public interface IRestriction<T> : IRestriction
where T:struct
{
// hide IRestriction.Limit
new T Limit {get;}
}
public abstract class RestrictionBase<T> : IRestriction<T>
where T:struct
{
// explicit implementation
object IRestriction.Limit
{
get { return Limit; }
}
// override when required
public virtual T Limit { get; set; }
}
public class TimeRestriction : RestrictionBase<TimeSpan>
{
}
public class AgeRestriction : RestrictionBase<TimeSpan>
{
}
public class BlockRule : AbstractBlockRule
{
public override List<IRestriction> Restrictions { get; set; }
}
I also showed using a base restriction class here, but it is not required.
The runtime treats IRestriction<TimeSpan> and IRestriction<int> as different distinct classes (they even have their own set of static variables). In your case the only classes common to both IRestriction<TimeSpan> and IRestriction<int> in the inheritance hierarchy are IRestriction and object.
So indeed, having a list of IRestriction is the only sensible way to go.
As a side note: you have a property Limit in there that you might want to access regardless of whether you're dealing with an IRestriction<TimeSpan> or IRestriction<int>. What I would do in this case is to define another property object Limit { get; } on IRestriction, and hide it in the actual implementation. Like this:
public interface IRestriction
{
object Limit { get; }
}
public interface IRestriction<T> : IRestriction
where T : struct
{
new T Limit { get; set; }
}
public class TimeRestriction : IRestriction<TimeSpan>
{
public TimeSpan Limit { get; set; }
// Explicit interface member:
// This is hidden from IntelliSense
// unless you cast to IRestriction.
object IRestriction.Limit
{
get
{
// Note: boxing happens here.
return (object)Limit;
}
}
}
This way you can access Limit as object on all your IRestriction when you don't care what type it is. For example:
foreach(IRestriction restriction in this.Restrictions)
{
Console.WriteLine(restriction.Limit);
}
Interfaces are contracts that need to be followed by the entity that implements the contract.
You have created two contract with the same name IRestriction
As far as I can see, what you are basically may need is a flag for classes that can be restricted, which should implement the IRestriction non-generic interface.
The second interface seems to be restrictable objects that also contain a limit property.
Hence the definition of the second IRestriction interface can be ILimitRestriction or whatever name suits your business needs.
Hence ILimitRestriction can inherit from IRestriction which would mark classes inheriting ILimitRestriction still objects of IRestriction
public abstract class AbstractBlockRule
{
public long Id{get;set;}
public abstract List<IRestriction> Restrictions {get;};
}
public interface IRestriction{}
public interface IRestrictionWithLimit<T>:IRestriction where T:struct
{
T Limit {get;}
}
public TimeRestriction:IRestrictionWithLimit<TimeSpan>
{
public TimeSpan Limit{get;set;}
}
public AgeRestriction:IRestrictionWithLimit<int>
{
public int Limit{get;set;}
}
public class BlockRule:AbstractBlockRule
{
public virtual List<IRestriction> Restrictions {get;set;}
}
I have a lot of similar classes generated by svcutil from some external WSDL file. Any class has a Header property and string property which named class name + "1".
For instance, I have classes: SimpleRequest that has Header property and SimpleRequest1 property.
Another one is ComplexRequest that has Header property and ComplexRequest1 property.
So, I want to create a common interface for such classes. So, basically I can define something like that:
interface ISomeRequestClass {
string Header;
// here is some definition for `class name + "1"` properties...
}
Is it possible to define such member in interface?
Here is post edit goes...
Here is sample of generated class:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class SimpleRequest
{
public string Header;
[System.ServiceModel.MessageBodyMemberAttribute(Name="SimpleRequest", Namespace="data", Order=0)]
public SimpleRequestMsg SimpleRequest1;
public SimpleRequest()
{
}
public SimpleRequest(string Header, SimpleRequestMsg SimpleRequest1)
{
this.Header = Header;
this.SimpleRequest1 = SimpleRequest1;
}
}
POST EDIT 2
I changed definition of this annoying +1 property to represent real actual picture. It's all has different class types. So how can I pull it out to common interface?
POST EDIT 3
Here is coupled question that could bring more clarify.
EDIT (after seeing your code sample): Technically speaking, your code does not have a Header property, it has a Header field. This is an important difference, since you cannot specify fields in an interface. However, using the method described below, you can add properties to your classes that return the field values.
Is it possible to define such member in interface?
No, interface names cannot be dynamic. Anyway, such an interface would not be very useful. If you had an instance of class ISomeRequestClass, what name would you use to access that property?
You can, however, use explicit interface implementation:
interface ISomeRequestClass {
string Header { get; set; }
string ClassName1 { get; set; }
}
class SomeClass : ISomeRequestClass {
string Header { ... }
string SomeClass1 { ... }
// new: explicit interface implementation
string ISomeRequestClass.ClassName1 {
get { return SomeClass1; }
set { SomeClass1 = value; }
}
}
You could define your interface more generally:
interface ISomeRequestClass {
string HeaderProp {get; set;}
string Prop {get; set;}
}
And your concrete classes could be extended (in an extra code file) by mapping interface members to class fields like so:
public partial class SimpleRequest : ISomeRequestClass
{
public string HeaderProp
{
get
{
return Header;
}
set
{
Header = value;
}
}
public string Prop
{
get
{
return SimpleRequest1;
}
set
{
SimpleRequest1= value;
}
}
}
Putting aside for a moment the naming of your classes and properties.
If you're looking to create an interface with a property relevant to your specific +1 type, you have a couple of options.
Use a base class for your +1's
If both of your +1 classes inherit from the same base class you can use this in your interface definition:
public interface IFoo
{
[...]
PlusOneBaseType MyPlusOneObject{get;set;}
}
Create a generic property on your interface
This method allows you to specify the type for the +1 property as a generic parameter:
public interface IFoo<TPlusOneType>
{
[...]
TPlusOneType MyPlusOneObject{get;set;}
}
Which you might use like:
public class SimpleRequest : IFoo<SimpleRequest1>
{
[...]
}
Update
Given that your classes are partial classes, you could always create a second (non machine generated) version of the partial class that impliments your interface.
You mentioned svcutil so I assume you are using these classes as WCF DataContracts?
If that is the case then you could make use the name property of DataMemberAttribute.
interface IRequest
{
string Header { get; set; }
string Request1 { get; set; }
}
[DataContract]
class SimpleRequest : IRequest
{
[DataMember]
public string Header { get; set; }
[DataMember(Name="SimpleRequest1"]
public string Request1 { get; set; }
}
[DataContract]
class ComplexRequest : IRequest
{
[DataMember]
public string Header { get; set; }
[DataMember(Name="ComplexRequest1"]
public string Request1 { get; set; }
}
If you are concerned giving yourself more work when you regenerate the code at some point in the future, then I recommend you write a PowerShell script to do this transformation automatically. After all svcutil is just a script written by some guy at Microsoft. It is not magic or "correct" or "standard". Your script can make a call to scvutil and then make a few quick changes to the resulting file.
EDIT (After seeing your edit)
You are already using MessageBodyMemberAttribute's Name property so just change this:
public string SimpleRequest1;
To
public string Request1;
Do you actually need these classes to have a common interface? I'd be tempted to instead create a wrapper interface (or just a concrete class) which could then use reflection to access the fields in question:
// TODO: Make this class implement an appropriate new interface if you want
// to, for mocking purposes.
public sealed class RequestWrapper<TRequest, TMessage>
{
private static readonly FieldInfo headerField;
private static readonly FieldInfo messageField;
static RequestWrapper()
{
// TODO: Validation
headerField = typeof(TRequest).GetField("Header");
messageField = typeof(TRequest).GetField(typeof(TRequest).Name + "1");
}
private readonly TRequest;
public RequestWrapper(TRequest request)
{
this.request = request;
}
public string Header
{
get { return (string) headerField.GetValue(request); }
set { headerField.SetValue(request, value); }
}
public TMessage Message
{
get { return (TMessage) messageField.GetValue(request); }
get { messageField.SetValue(request, value); }
}
}
You could use expression trees to build delegates for this if the reflection proves too slow, but I'd stick to a simple solution to start with.
The advantage of this is that you only need to write this code once - but it does mean creating a wrapper around the real request objects, which the partial class answers don't.
I understand how the "new" keyword can hide methods in a derived class. However, what implications does it have for classes that implement interfaces that use the keyword?
Consider this example, where I decide to expand an interface by making its properties read/write.
public interface IReadOnly {
string Id {
get;
}
}
public interface ICanReadAndWrite : IReadOnly {
new string Id {
get;
set;
}
}
Then you are able to do things like this:
public IReadOnly SomeMethod() {
// return an instance of ICanReadAndWrite
}
Is this bad design? Will it cause issues for my classes that implement ICanReadAndWrite?
Edit: Here is a contrived example of why I might want to do something like this:
Say I have a factory class that returns an IShoppingCartItemReadWrite. I can then have a service layer that manipulates prices on it, changes stuff, etc. Then, I can pass these objects as IShoppingCartItemReadOnly to some kind of presentation layer that won't change them. (Yes, I know it technically can change them-- this is a design question, not security, etc.)
It's not a particularly bad idea. You should be aware that the implementor can (if it implicitly implements the interface, then a single read/write property could satisfy both interfaces) provide two distinct implementations:
class Test : ICanReadAndWrite {
public string Id {
get { return "100"; }
set { }
}
string IReadOnly.Id {
get { return "10"; }
}
}
Test t = new Test();
Console.WriteLine(t.Id); // prints 100
Console.WriteLine(((IReadOnly)t).Id); // prints 10
By the way, in general, the new inheritance modifier does nothing except to tell the compiler to shut up and don't throw out a "you're hiding that member" warning. Omitting it will have no effect in the compiled code.
You should not implement the ICanReadWrite based on IReadOnly, but instead make them separate.
ie. like this:
public interface IReadOnly
{
string Id
{
get;
}
}
public interface ICanReadAndWrite
{
string Id
{
get;
set;
}
}
Here's a class using them:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
}
Note that the same property in the class can support both interfaces.
Note that as per the comment, the only way to get a robust solution would be to also have a wrapper object.
In other words, this is not good:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
public IReadOnly AsReadOnly()
{
return this;
}
}
as the caller can just do this:
ICanReadWrite rw = obj.AsReadOnly() as ICanReadWrite;
rw.Id = "123";
To get a robust solution, you need a wrapper object, like this:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
public IReadOnly AsReadOnly()
{
return new ReadOnly(this);
}
}
public class ReadOnly : IReadOnly
{
private IReadOnly _WrappedObject;
public ReadOnly(IReadOnly wrappedObject)
{
_WrappedObject = wrappedObject;
}
public string Id
{
get { return _WrappedObject.Id; }
}
}
This will work, and be robust, right up until the point where the caller uses reflection.
This is perfectly legal and the implications for your class that implements the ICanReadAndWrite interface would simply be that when it is treated as an IReadOnly it can only read, but when treated as ICanReadAndWrite it would be able to do both.
I'm not sure if that compiles or not, but is not an advisable pattern to follow. With the ability to do explicit interface implementation, you could theoretically provide two entirely different implementations for the IReadOnly and ICanReadAndWrite versiond of the Id property. Consider altering the ICanReadAndWrite interface by adding a setter method for the property rather than replacing the property.
You can do it but I am not sure what you hope to accomplish by doing it.
public IReadOnly SomeMethod() {
// return an instance of ICanReadAndWrite
}
This method will return a reference to an IReadOnly which means that it doesn't matter that you have returned an ICanReadAndWrite. Wouldn't this approach be better?
public interface IReadOnly
{
String GetId();
}
public interface ICanReadAndWrite : IReadOnly
{
String SetId();
}