如何初始化结构?
我应该在我的任意结构中实现什么成员来进行以下任务:
public struct MyStruct { String s; Int length; } MyStruct myStruct = new MyStruct { s = "Hello", length = 5 }; // Now, I want the following code to set the 's' to "Lol" and the // length to 3 (length of "Lol"). The second part should be done // automatically. myStruct = "Lol"; // Or myStruct = String("Lol");
这应该怎么做?
您使用隐式运算符将string值转换为结构值:
public struct MyStruct { public string s; public int length; public static implicit operator MyStruct(string value) { return new MyStruct() { s = value, length = value.Length }; } }
例:
MyStruct myStruct = "Lol"; Console.WriteLine(myStruct.s); Console.WriteLine(myStruct.length);
输出:
Lol 3
结构types应该在任何可行的情况下,将其所有状态封装在公共字段中,这些公有字段可以独立地设置为对于它们各自的types有效的任何值,或者performance为只能通过构造函数,工厂,方法,或者通过将结构的一个实例作为一个显式的ref
parameter passing给它的一个公共方法。 与一些人所声称的相反,如果一个结构体具有公有字段,那么它应该表示一组值,这些值可能被单独操作或者作为一组传递(例如一个点的坐标)。 从历史上看,有公共财产制定者的结构存在问题,并且希望避免公共领域(意味着应该使用制定者),这使得一些人认为应该完全避免可变结构,但是领域没有问题属性了。 事实上,暴露域结构是一个松散的自variables集合的理想表示,因为它只是一个松散的variables集合。
然而,在你的特定例子中,看起来你的结构的两个字段可能不应该是独立的。 有三种方法可以明智地devise你的结构:
-
你可以有唯一的公共字段是string,然后有一个只读的“助手”属性称为
length
,如果string是非空的,将报告其长度,如果string为空则返回零。 -
您可以让结构不公开任何公共字段,属性设置器或变异方法,并且只在对象的构造函数中指定唯一字段(私有string)的内容。 如上所述,
length
将是一个属性,将报告存储的string的长度。 -
你可以让结构不暴露任何公共字段,属性设置器或者变异方法,并且有两个私有字段:一个用于string,另一个用于长度,两者都将被设置在一个构造函数中,该构造函数接受一个string,将其存储,测量其长度,并将其存储。 确定string的长度足够快,以至于计算和cachingstring可能是不值得的,但是将string和它的
GetHashCode
值组合起来的结构可能是有用的。
但是,了解第三个devise的细节很重要:如果非线程安全代码导致在另一个线程写入结构时读取一个结构实例,则可能会导致意外创build一个结构实例字段值不一致。 由此产生的行为可能会有点不同于那些类以非线程安全方式使用时的行为。 任何与安全有关的代码都必须小心,不要认为结构字段的状态是一致的,因为即使在“完全信任”环境中,恶意代码也可以轻松生成状态不一致的结构,它想要做的。
PS – 如果你希望允许使用string赋值来初始化你的结构,我会build议使用一个隐式转换运算符,并使Length
成为一个只读属性,如果返回非空,则返回基础string的长度,如果string为空,则为零。
-
“长度”是否会偏离“s”的实际长度? 如果答案是否定的,那么你不需要存储长度,因为string已经存储了它们的长度,你可以调用s.Length。
-
为了获得你所要求的语法,你可以像这样实现一个“隐式”运算符:
static implicit operator MyStruct(string s) { return new MyStruct(...); }
-
隐式运算符将工作,无论你是否使你的结构可变。
你的结构可以有方法和属性…为什么不尝试
public struct MyStruct { public string s; public int length { return s.Length; } }
纠正 @ Guffa的答案显示,这是可能的…更多信息在这里: http : //www.codeproject.com/KB/cs/Csharp_implicit_operator.aspx