0

I have a problem with interfaces in C#. I made an interface called IPerson that needs a name and age. After that I created a class that inherits from that interface, so it needs a name and age. When I try to write these variables in the class, they can only be public and I don't understand why.

public interface IPerson
{
    string name { get; set; }
    int age { get; set; }
}

public class Person : IPerson
{
    // If I try to make them private or protected, they don't work. and IPerson will be colored red. Only if they are public it's good, why ?
    private string name { get; set; } 
    private int age { get; set; }
}
David
  • 624
  • 1
  • 6
  • 21
  • 4
    Why do you need to do this? an *interface* is like a declaration to the world you support something. I.e "*my shop supports cashless payments!!!!*" only to hide it... It really doesn't make sense. In short, there is no point declaring that you support something, and declaring it private so no one knows. You need to rethink your problem and justify to your self why you actually need an interface – TheGeneral Feb 23 '20 at 23:28
  • @MichaelRandall sometimes people have to implement an interface to integrate their code into a framework but have no desire to expose that interface to other parts of their code which don't need or use the interface. In this circumstance I would implement the interface explicitly – Mick Feb 24 '20 at 00:03
  • @Mick agreed. However, this is a hack which .net designed to solve another problem, and yes it does goes to lengths to hide it, though i highly doubt this is the case for the OP and is likely a miss understanding about why the OP needs an interface and leading to a larger code smell and questionable design. – TheGeneral Feb 24 '20 at 00:09
  • 1
    @MichaelRandall who knows why David wants to hide the implementation of his interface. I doubt this code is more than an example. Buckets of reasons for hiding the public implementation of an interface here https://stackoverflow.com/questions/4103300/why-implement-interface-explicitly – Mick Feb 24 '20 at 00:17
  • @Mick That is why i used the word *likely*. My notes are there as *fair warning*, and also should be noted an explicit implementation is not private and in most situations would fail a code review. Good luck to you both :) – TheGeneral Feb 24 '20 at 00:26
  • 1
    @MichaelRandall not sure I need luck, would never rely on it in a production system. But thanks anyhow. Granted, explicit implementations of interfaces should be uncommon if not completely absent in most code, however there are valid exceptions. Good chance you're right that David's motivations probably don't fall into that category, but everyone goes has to go through a learning process. – Mick Feb 24 '20 at 01:02

3 Answers3

3

Perhaps what you want is to implement the interface explicitly...

e.g.

public interface IPerson
{
    string Name { get; set; }
    int Age { get; set; }
}

public class Person : IPerson
{
    string IPerson.Name { get; set; } 
    int IPerson.Age { get; set; }
}

These members can only be accessible publicly via a reference to the interface.

i.e You can't do the following...

Person me = new Person();
Console.WriteLine(me.Name);  // Won't compile

but you can do the following...

IPerson me2 = new Person();
Console.WriteLine(me2.Name); // Will compile
Mick
  • 6,527
  • 4
  • 52
  • 67
2

An interface is a kind of contract that you state. Everything declared in the interface needs to be accessible in the type that inherits from said interface. When you now declare a method as private, you can't access it from the other object which tries to enact the contract, resulting in the interface not being implemented correctly.

This is also the reason, why interfaces do not have accessor declarations. The properties, methods and events defined in the interface are required to be public, because otherwise accessing the class instance through the interface would not work.

In your example, you derive Person from IPerson. Now imagine, you use it like this:

IPerson c = GetCustomer();

where GetCustomer is defined like this:

public IPerson GetCustomer() {
    // internal code
}

All you have access to now, is the given values declared in the interface. This means that name and age are defined in the interface and are accessible.
Let's say, Person also declares some other properties, like IPerson parent { get; set; }. In this case, the parent may be of type Person or of any other type that inherits from IPerson. But you can always be sure that the object that gets assigned to this property derives from IPerson and will have the properties name and age defined.

There is also no reason to declare an interface for private members. What would be the benefit your code has from that? Interfaces exist to connect objects that do not know much about the other type, except the interface. Think of it, as a power plug: You plug it into the socket, but it does not care where the power comes from. And likewise, the socket doesn't care where the power is going. It is just the case that both use an interface the other can interact with.
Using an interface in a class just for itself would be pointless, because there is no information that is hidden or needs to be abstracted within a class.

Max Play
  • 3,717
  • 1
  • 22
  • 39
1

As Max Play said:

An interface is a kind of contract that you state. Everything declared in the interface needs to be accessible in the type that inherits from said interface.

Everything you place in an interface, must be accessible in any instance of your implemented object, unless it is used within it an explicit implementation.

But if you still want to use a pattern where you want to choose which property can be private, public or protected, an option is to create an abstract class, instead of the interface

EveRegalado
  • 105
  • 1
  • 8
  • 1
    "Everything you place in an interface, must be accessible in any instance of your implemented object." - is not true. Wat about explicit implementations? – Enigmativity Feb 23 '20 at 23:45
  • 1
    @Enigmativity Even if it's implemented explicitly, it's still always accessible, it just means you need to access it through the interface instead of the class itself. – Servy Feb 23 '20 at 23:47
  • @Servy - Yes, but Eve wrote "accessible **in** any instance of your implemented object.". It's only accessible when go go via the interface. – Enigmativity Feb 24 '20 at 00:18
  • @Enigmativity you are right, because I never had to force an explicit implementation – EveRegalado Feb 24 '20 at 00:35