C# C语言中的封装问题#
我在C#中的封装方面遇到了一些问题。有两种特定的情况会给我带来问题,我相信这是相关的 情景1 我有一个类似这样的类定义C# C语言中的封装问题#,c#,enumeration,accessor,C#,Enumeration,Accessor,我在C#中的封装方面遇到了一些问题。有两种特定的情况会给我带来问题,我相信这是相关的 情景1 我有一个类似这样的类定义 class MyClass { private int _someField; private OtherClass _otherClass; public int someField { get { return _someField; } set { _someField = value; } } public OtherClas
class MyClass
{
private int _someField;
private OtherClass _otherClass;
public int someField
{
get { return _someField; }
set { _someField = value; }
}
public OtherClass otherClass
{
get { return _otherClass; }
set { _otherClass = value; }
}
}
如果我尝试在一段新代码中执行类似的操作
MyClass theClass = new MyClass();
theClass.otherClass.XYZ += 1;
我被告知无法修改“MyClass.otherClass”的返回值,因为它不是变量
情景2#
我被告知-foreach语句无法对“trksegType”类型的变量进行操作,因为“trksegType”不包含“GetEnumerator”的公共定义
即使数组应该隐式允许枚举
有人能解释一下发生了什么,我能做些什么来解决这个问题,同时保持最佳实践。我看不出您的第一个示例有任何错误-因此,请仔细检查错误的示例是否确实存在,如果没有,请更正
在第二个实例中,看起来您正在尝试迭代trksegType的实例,而不是包含的trkpt属性。请尝试使用
foreach(trk.trkseg[i].trkpt中的wptType-way)
。我看不出您的第一个示例有任何错误,因此请仔细检查错误的示例是否确实存在,如果没有,请更正
在第二个实例中,看起来您正在尝试迭代trksegType的实例,而不是包含的trkpt属性。请尝试使用
foreach(trk.trkseg[i].trkpt中的wptType方式)
。对于场景1,我怀疑其他类已定义为结构。当从属性访问器访问结构时,将创建并返回该结构的新副本(即结构)。更改此新副本上的属性不会对原始结构产生影响
C#编译器检测到这一点,并引发稍微模糊的错误 对于场景1,我怀疑OtherClass已被定义为结构。当从属性访问器访问结构时,将创建并返回该结构的新副本(即结构)。更改此新副本上的属性不会对原始结构产生影响 C#编译器检测到这一点,并引发稍微模糊的错误 场景1: 原因很可能是因为您的
OtherClass
是一个结构而不是类。值语义有点棘手,可变值类型被认为是有害的。因此,您要么希望将OtherClass
设置为类而不是结构,要么按照以下思路进行操作:
struct OtherClass
{
public int XYZ { get; }
public OtherClass(int xyz)
{
XYZ = xyz;
}
public OtherClass AddToXYZ(int count)
{
return new OtherClass(this.XYZ + count);
}
}
那你就可以了
myClass.otherClass = myClass.otherClass.AddToXYZ(1);
情景2:
您需要在trksegType
上实现IEnumerable
以枚举trkpt
或实际访问trkpt
以进行枚举
一般而言:
通过其他对象访问对象违反了这两种情况下的封装。请看这里:
<>你也应该考虑为对象使用更好的(更明确的)名称。mttng vwls ds nt NCR rdblty.场景1:
原因很可能是因为您的OtherClass
是一个结构而不是类。值语义有点棘手,可变值类型被认为是有害的。因此,您要么希望将OtherClass
设置为类而不是结构,要么按照以下思路进行操作:
struct OtherClass
{
public int XYZ { get; }
public OtherClass(int xyz)
{
XYZ = xyz;
}
public OtherClass AddToXYZ(int count)
{
return new OtherClass(this.XYZ + count);
}
}
那你就可以了
myClass.otherClass = myClass.otherClass.AddToXYZ(1);
情景2:
您需要在trksegType
上实现IEnumerable
以枚举trkpt
或实际访问trkpt
以进行枚举
一般而言:
通过其他对象访问对象违反了这两种情况下的封装。请看这里:
<>你也应该考虑为对象使用更好的(更明确的)名称。mttng vwls ds nt NCR rdblty.(你真的不应该在一个问题中提出两个问题。)
情景1
无法修改“MyClass.otherClass”的返回值,因为它不是变量
发生此错误的原因是OtherClass
不是类,而是结构-也称为值类型。这意味着访问MyClass.otherClass将复制该值,而不是返回引用。您将修改此副本,这将是毫无意义的。编译器捕捉到了这一点,因为它总是一个bug,从来没有用过
情景2
您没有告诉我们什么是trkseg[i]
,但是如果它是trksegType
类型,那么答案是:因为trksegType
不允许任何枚举。它没有实现IEnumerable
,IEnumerable
,也没有自己的GetEnumerator
方法
也许你想写:
foreach (wptType way in trk.trkseg[i].trkpt)
因为trkpt
是wptType
的数组。(如果使用更有意义的变量名,而不是毫无意义的奇怪字母组合,您可能会更快地发现此错误。)(您真的不应该在一个问题中发布两个问题。)
情景1
无法修改“MyClass.otherClass”的返回值,因为它不是变量
发生此错误的原因是OtherClass
不是类,而是结构-也称为值类型。这意味着访问MyClass.otherClass将复制该值,而不是返回引用。您将修改此副本,这将是毫无意义的。编译器捕捉到了这一点,因为它总是一个bug,从来没有用过
情景2
您没有告诉我们什么是trkseg[i]
,但是如果它是trksegType
类型,那么答案是:因为trksegType
不允许任何枚举。它没有实现IEnumerable
,IEnumerable
,也没有自己的GetEnumerator
方法
也许你想写:
foreach (wptType way in trk.trkseg[i].trkpt)
因为trkpt
是wptType
的数组。(如果使用更有意义的va,您可能会更快地发现此错误