Tara
Tara

Reputation: 397

How can I give nested structs access to fields of their parent classes without making those fields public or internal?

I have a double[,] field in a class, and it's important that direct access to it not be given over to the outside, so I created a read-write property to control it and made it private. I also have a nested struct in the class, which I want to keep as a value-type. The struct itself has a double[,] field, which again, is controlled by a corresponding read-write property. Given certain conditions, if the property is assigned a value that's invalid in a specific way, it throws a custom exception. One of the arguments I need to pass to the exception is based on the value of the double[,] field from the parent class, but I don't seem to be able to access it from within the struct without making it public or internal. I've tried both protected and private but neither works. Is there another workaround?

class myClass {
    protected double[,] classField;
    public double[,] classProperty {
        get { return (double[,])classField.Clone();
        set { /* code to validate the value and assign it */ }
    }
    private struct myStruct {
        private double[,] structField;
        public structProperty{ 
            get { return (double[,])structField.Clone(); }
            set {
                if (!validate(value)) 
                    throw new customException(classField.getLength(1));
                structField = (double[,])value.Clone();
            }
        }
        //other fields, constructors, and methods...
    }
    //other fields, constructors, and methods...
}

I was considering possibly accessing the property instead of the field, but I would need the value of the property for the particular instance that contanins the struct instance in question. Is there maybe something like this.parent (I did try that and that didn't work, but maybe some workaround similar in concept)?

Upvotes: 2

Views: 1233

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1064204

I'm assuming that you want myStruct to talk to the classField of the containing myClass instance.

If that is the case: then the problem isn't accessibility - it already has access; the problem is scope. As far as the compiler is concerned, nesting here is unrelated to instancing, so the problem is that myStruct has no specific instance of classProperty to talk to. That's why the error is:

Error CS0120 An object reference is required for the non-static field, method, or property 'myClass.classField'

rather than accessibility:

Error CS0122 'myClass.classField' is inaccessible due to its protection level

In fact, classField can be private in terms of accessibility: a nested type can see private members of the containing type.

What you would need is to do something like:

private struct myStruct
{
    private readonly myClass _obj;
    public myStruct(myClass obj) => _obj = obj;
    // ...
}

and then instead of just classField, you need to tell it to talk to _obj.classField to tell it the instance. You would also need to construct the myStruct passing in the specific myClass to which it relates.

Basically: the this.parent concept you mention in the question is not implicit - you need to implement it yourself.

Upvotes: 3

Related Questions