Thought this was a duplicate question but other questions are all slightly different.
I have some parent interfaces and inheriting classes like this:
public interface IPerson
{
IPersonData PersonData {get;}
//other stuff
}
public interface IPersonData
{
public String Name {get;}
//other stuff
}
public class Person : IPerson
{//need to implement IPersonData
IPersonData PersonData {get;set;} = new PersonData();
//other stuff
PersonData.Name = "JohnDoe";//compiler error somewhere in a method
}
public class PersonData : IPersonData
{//need to implement IPersondata
public String Name {get;set;}
//other stuff
}
So my goal as you can see is to implement the IPerson
interface while also being able to write to the Name property of the IPersonData (instantiated as a PersonData). As the code is written here, if I tried to do PersonData.Name = "JohnDoe" the compiler will throw an error because the property is apparently read-only. If I try to change IPersonData to be PersonData pd = New PersonData, then I am obviously no longer implementing the interface requirement.
I have to do this because these are interfaces that are required and are not written or controlled by me. When these interfaces were written originally they were done in a time where they probably didn't have auto-fielded properties.
What I know is that I could implement a field behind it and have the program write to the field when I need to write, and the property can reference the field. However, I feel this is probably not the "correct" way to do things in c# in 2021 where everything is a property and it adds lines of code I feel are probably not needed.
So is there a more "correct" way to do this if I cannot rewrite the interface, or is adding a field the only thing that can be done?
Before someone says "this question has been answered by such and such before" please make sure they are not referring to an INTERFACE inheriting another interface, where that actually does work. Apparently, this issue only exists when a concrete class inherits an interface.
CodePudding user response:
You can achieve your goal by explicitly implementing the interface. In this example, my implementation makes use of the existing property (adjusted to type PersonData
):
public class Person : IPerson
{//need to implement IPersonData
public PersonData PersonData { get; set; } = new PersonData();
IPersonData IPerson.PersonData => PersonData;
//other stuff
}
The code
Person fred = new Person();
fred.PersonData.Name = "Fred";
Console.WriteLine(fred.PersonData.Name);
outputs
Fred
The class now fulfills the contract of IPerson
and provides additional functionality not defined in a contract (interface).