Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# References; Keeping Members Hidden

Imagine you have a class defined as follows.

public class SomeClass
{
     public Manager m { get; protected set; }
     public SpecialData data { get; protected set; }

     //More methods and member code here...
}

I need my manager class to somehow be able to change the set reference for the SpecialData member. I could do this with a double pointer or friend classes in C++, but that option isn't available in C#, sadly. How do I keep SpecialData protected from outside users setting it, while still allowing the Manager class control over setting? I could do this with internal keyword, but that doesn't seem incredibly safe or clean...

Any help is greatly appreciated.

like image 207
guitar80 Avatar asked Sep 18 '14 14:09

guitar80


People also ask

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What is C language used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...


4 Answers

If the manager class is part of the same assembly as SomeClass, making the member internal would make it possible for classes in the same assembly to access the setter:

public SpecialData data { get; protected internal set; }

This is similar to using friend in C++, with the exception that the "friendship" is extended to all members of the same assembly.

If the manager is part of a different package, you can use InternalsVisibleTo attribute on your assembly. In this case, however, you should sign the assembly to which you extend friendship to avoid attempts to gain access to the setter from unauthorized code.

like image 133
Sergey Kalinichenko Avatar answered Sep 29 '22 21:09

Sergey Kalinichenko


What about creating an event on the Manager class, something like a RequestChangeSpecialData event. The Manager fires the event, and the SomeClass will change the SpecialData instance.

public class SomeClass
{
     private  Manager _m;

     public Manager M 
     { 
        get { return _m} 
        set 
        {
            // register/unregister event on property assignment
            if(_m != null)
                _m.RequestChangeSpecialData -= RequestChangeSpecialData;

            _m = value;

            if(_m != null)
                _m.RequestChangeSpecialData += RequestChangeSpecialData;

        }
     }

     public SpecialData Data { get; private set; }

     private void RequestChangeSpecialData(object sender, ChangeSpecialDataEventArgs e)
     {
        // set the new reference
        Data = e.SpecialData;
     }

}

public class Manager
{
    public void DoSomething()
    {
        // the manager class wants to do something, and wants to change the SpecialData instance.., so it fires the event RequestChangeSpecialData


        SpecialData data = new SpecialData();

        // if the event is bound.
        if(RequestChangeSpecialData != null)
            RequestChangeSpecialData(this, new ChangeSpecialDataEventArgs(data));
    }

    public event EventHandler<ChangeSpecialDataEventArgs> RequestChangeSpecialData;
}

public class ChangeSpecialDataEventArgs : EventArgs
{
    public SpecialData Data {get; private set; }

    public ChangeSpecialDataEventArgs(SpecialData Data)
    {
        Data = data;
    }
}

UNTESTED (wrote in notepad)

Now the Manager is able to change the SpecialData property. This way the manager is not dependent from the SomeClass/interface or assembly.

like image 45
Jeroen van Langen Avatar answered Sep 29 '22 20:09

Jeroen van Langen


It might not be exactly what you are looking for, but the internal keyword described here can govern access within the same assembly; it seems a similar purpose as the friend keyword in C++.

like image 37
Codor Avatar answered Sep 29 '22 22:09

Codor


You could make the property internal. That will make the property only visible inside the same assembly. Optionally you could use the InternalsVisibleToAttribute to allow specific assemblies access to that property.

Another approach is the use of an interface to hide that property:

public interface ISomeClass
{
     Manager m { get; }
     SpecialData data { get; set; }
}

public class SomeClass : ISomeClass
{
     public Manager m { get; protected set; }
     SpecialData ISomeClass.data { get; set; }

     //More methods and member code here...
}

In this way, data is only visible from interface reference.

So this doesn't work:

SomeClass c = new SomeClass();
c.data;

But this does:

ISomeClass c = new SomeClass();
c.data;
like image 36
Patrick Hofman Avatar answered Sep 29 '22 20:09

Patrick Hofman