Yekoor
Yekoor

Reputation: 73

How to control class visibility by owner in c#

Often I want some (or all) functions of some class C1 to be accessible only from within another class C2, because C2 is kind of a proxy, it owns objects of type C1 (e.g.: methods of a class "Neuron", like "connect()", should only be accessible from "Brain"). I assume this is not directly possible with C# unlike with inheritance, where we can specify visibility with a keyword like "private" or "protected".

What is the best practice in such a situation?

Upvotes: 4

Views: 335

Answers (4)

d--b
d--b

Reputation: 5779

In my opinion, the best for you is to do something like this:

public interface INeuron 
{
   double GetValue();
   List<INeuron> GetDependents();
   List<double> GetWeights();
}

internal class Neuron : INeuron
{
   // implementation of INeuron
   // ...

   // implementation of methods only known to own classes
   public void Connect(Neuron target, double weight)
   {
      ...
   }
}

public class Brain
{
   private List<Neuron> _allNeurons = new List<Neuron>();       

   public Brain()
   {
      Neuron n1 = new Neuron();
      Neuron n2 = new Neuron();
      n1.Connect(n2,0.5);
      _allNeurons.Add(n1);
      _allNeurons.Add(n2);
   }

   public IEnumerable<INeuron> GetAllNeurons() { return _allNeurons.Cast<INeuron>(); }
}

Upvotes: 0

CodeCaster
CodeCaster

Reputation: 151586

Create an assembly for your classes and declare the internal class that should not be visible to the outside world as internal:

internal (C# Reference):

The internal keyword is an access modifier for types and type members. Internal types or members are accessible only within files in the same assembly

So, something like this:

namespace YourAssembly.Classes
{
    internal class C1
    {
        public void Foo()
        {
        
        }
    }
    
    public class C2
    {
        public void DoFoo()
        {
            new C1().Foo();     
        }
    }
}

Here C2 is accessible from other assemblies, while C1 can only be accessed from within the same assembly.

Upvotes: 5

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112279

A trick often used for testing purposes is to use the InternalsVisibleToAttribute. You apply it to an assembly (exe or dll) like this

[assembly: InternalsVisibleTo("NameOfFriendAssembly")]

Classes (and other types) and members defined as internal will then be visible internally of cause but also to the assembly NameOfFriendAssembly

Upvotes: 0

Mike Perrenoud
Mike Perrenoud

Reputation: 67898

If C1 cannot be accessed by anybody but C2, then make C1 a private class of C2.

public class C2
{
    public C2() { }

    private class C1
    {
        public C1() { }
    }
}

However, if C1 can be accessed outside of C2, then you're going to need to pass in some kind of key into the ctor of C2 to ensure it's a trusted proxy.

public class C1
{
    public C1(string key)
    {
        // verify that it's a valid proxy or user of this class via the key
    }
}

Upvotes: 3

Related Questions