C# 如何让嵌套结构访问其父类的字段而不使这些字段成为公共字段或内部字段?
我在一个类中有一个C# 如何让嵌套结构访问其父类的字段而不使这些字段成为公共字段或内部字段?,c#,access-modifiers,C#,Access Modifiers,我在一个类中有一个double[,]字段,对它的直接访问不能交给外部,这一点很重要,因此我创建了一个读写属性来控制它,并将其设置为私有的。我在类中还有一个嵌套的struct,我希望将其保留为值类型。结构本身有一个double[,]字段,该字段同样由相应的读写属性控制。给定某些条件,如果为属性指定了一个特定方式无效的值,它将抛出一个自定义的异常。我需要传递给异常的参数之一是基于父类的double[,]字段的值,但如果不将其设置为公共或内部,我似乎无法从结构内部访问它。我尝试了受保护的和私有的,但都
double[,]
字段,对它的直接访问不能交给外部,这一点很重要,因此我创建了一个读写属性来控制它,并将其设置为私有的
。我在类中还有一个嵌套的struct
,我希望将其保留为值类型。结构本身有一个double[,]
字段,该字段同样由相应的读写属性控制。给定某些条件,如果为属性指定了一个特定方式无效的值,它将抛出一个自定义的异常。我需要传递给异常
的参数之一是基于父类的double[,]
字段的值,但如果不将其设置为公共
或内部
,我似乎无法从结构内部访问它。我尝试了受保护的
和私有的
,但都不起作用。还有其他解决办法吗
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...
}
我正在考虑可能访问属性而不是字段,但是我需要特定实例的属性值,该实例包含有问题的struct实例。是否有类似的this.parent
(我确实尝试过,但没有成功,但可能有一些解决方法在概念上类似)?我假设您希望myStruct
与包含myClass
实例的类字段
对话
如果是这样的话:那么问题不在于可访问性——它已经可以访问了;问题在于范围。就编译器而言,这里的嵌套与实例无关,因此问题在于myStruct
没有可与之对话的classProperty
的特定实例。这就是错误的原因:
错误CS0120非静态字段、方法或属性“myClass.classField”需要对象引用
而不是可访问性:
错误CS0122“myClass.classField”由于其保护级别而不可访问
实际上,classField
在可访问性方面可以是private
:嵌套类型可以看到包含类型的private
成员
您需要做的是:
private struct myStruct
{
private readonly myClass _obj;
public myStruct(myClass obj) => _obj = obj;
// ...
}
然后,您需要告诉它与\u obj.classField
对话,而不仅仅是classField
,以告诉它实例。您还需要构造myStruct
来传递与之相关的特定myClass
基本上:你在问题中提到的this.parent
概念不是隐式的-你需要自己实现它。我可以检查一下:你想从myStruct访问myClass.classField吗?是的,没错,这不编译,结构可以有构造函数吗?@Jerry是的,它们可以;我在这里使用的是C#7.3语法-如果您使用的是早期的编译器:public myStruct(myClass obj){{{u obj=obj;}
我理解我的错误,它抱怨没有分配stuctField
,我正在使用OP的代码。感谢Marclol,您必须使用参数显式地模拟this.parent功能,这一点非常令人讨厌,但它可以工作。谢谢@TaraStahler的要点是:C#并不认为您的结构应该以任何方式跟踪“containing”实例-myStruct
完全由您编写的代码定义-没有隐藏的自动额外字段。这a:意味着您完全理解您正在创建的类型的大小/范围(这可能很重要),b:意味着它不会神奇地变成不可blittable(有一个引用某个父级的字段就可以了;blittable===t:unmanaged
),c:不会将myStruct
实例的使用限制为与myClass
实例的1:1关系