Search code examples
c#classpropertiesstructinternal

How to define a struct whose members can be accessed by any internal classes but can only be set by a particular (internal) class?


How to define a struct whose members can be accessed by any internal classes via properties but can only be set by a particular internal class? (If it is possible.)

If it is not possible, is there a work-about to achieve the similar requirement?

Edit 1: below

Reason:

I have a class A with two members _x and _arrB. _x can be read but not modified by internal classes (except class A) through x.

I also want to allow internal classes to read structB elements in _arrB and to read members of those structB. But I only want class A to be able to modify either a structB element in _arrB or a member of those structB. Hence I think I need a struct that can specify which internal classes can modify its member.[1]

class A 
{
    private int _x;
    internal int x
    {
        private set
        {
            _x = value / 2;
        }
        internal get
        {
            return _x * 2;
        }
    }

    private B[] _arrB;
    internal B[] arrB
    { 
        private set
        {
            _arrB = value;
        }
        internal get
        {
            return _arrB;
        }
    }

    public A() 
    {
        _x = //value read from somewhere;            

        //do something to determine size
        _arrB = new B[size];
        //populate _arrB
        ...
    }


}

Note: By internal class I mean a class in the same assembly, not a nested class.

[1] However, _arrB is an array, which is an object, which is a reference type. When an internal class gets a reference of _arrB, elements of structB may be modified without control. I realized that I do not want inner classes to set _arr[0] to null. So any solution have to take this into account.

I will think about it for the rest of the day and post a solution when I have thought of one.


Solution

  • I wonder why you want to do that. Only ugly hacks are possible AFAIK.

    BEGIN WARNING: do not read if you dislike ugly code!!!

    What David Neale said.

    You could put them in separate assemblies and set them to friendly:

    [assembly:InternalsVisibleToAttribute("assembly name", "key")]
    

    You could design the class like this:

    internal struct ModifiedStruct
    {
        public int Value {get; private set; }
    
        internal class ModifyingClass
        {
            public void ModifyValue()
            {
                ModifiedStruct s = new ModifiedStruct();
                s.Value = 456;
            }
        }
    
    }
    

    END WARNING

    Edit (question changed) To prohibit modification of a collection, use the ReadOnlyCollection Class.

    internal ReadOnlyCollection<B> BCollection
    {
        get
        {
            return new ReadOnlyCollection<B>(_arrB);
        }
    }