Make methods / properties visible to one class hidden by another

I have a Server class that talks about connecting to a server for IRC. It contains a list of known User s and creates them as needed.

I have two problems with the User class:

  • Anyone can create an instance of User . I want the Server class to be able to do this.
  • If a user ( User description) changes his name (or other information, for example, aggregated channels), the Server class can change it himself. However, other classes can too! I want to prevent other classes from touching this information (making it read-only).

How can I solve these two problems? In C ++, it can be solved using the friend keyword and making ctor and setName (and such) private.

Is there a C # keyword that can allow access to a specific method by a specific class? This will solve my problem.

+6
c # encapsulation
source share
3 answers

Honestly, I found access to a friend that came from C ++ to be a symptom of poor design. You better fix your design.

For starters, who really cares, does anyone create a user? Does it really matter? I ask this because it seems that sometimes we programmers get carried away with something that simply won’t happen, or if they do, it doesn’t matter.

If you really don't care, do one of the following:

  • Make user interface. The server can create an instance of a private class that implements it; or
  • Make the user an internal class of the Server without public designers, so only the server can create it.

The visibility of hacks (of which friends in C ++ are one, and batch access in Java are both good examples) just ask for troubles, not a good idea.

+8
source share

The closest in the .NET world to friend is internal visibility.

Note that if your two classes are in separate assemblies, you can use the InternalsVisibleTo attribute to allow the visibility of internal elements in the assembly of the other.

+5
source share

Reorganizing the class hierarchy is probably a fair solution to this problem. Since this sounds to me like what you really need, this is a read-only user class when it exists outside of the Server class.

I would probably do something like this:

 // An abstract base class. This is what I'd use outside the // Server class. It abstract, so it can't be instantiated // on its own, and it only has getters for the properties. public abstract class User { protected User() { } public string Name { get;} // Other get-only properties } public class ServerUser : User { public ServerUser() { } public string Name { get; set;} // Other properties. } 

Then create the ServerUser classes of the Server class, the custom server class will change the properties in the ServerUser classes (for example, change the username), but only bring the user classes to the outside world.

+1
source share

All Articles