gpt4 book ai didi

c# - 类如何防止外部代码声明其类型的变量?

转载 作者:行者123 更新时间:2023-11-30 15:46:02 25 4
gpt4 key购买 nike

一个类是否有可能暴露一种类型的函数返回,而又不允许该类的用户创建该类型的变量?几个使用场景:


大类的Fluent接口;这样的语句:“ foo = bar.WithX(5).WithY(9).WithZ(19);”如果必须创建该类的三个新实例,效率将会很低,但是如果WithX可以创建一个实例,而其他语句可以简单地使用它,则效率可能更高。
一个类可能希望支持类似“ foo [19] .x = 9;”的语句。即使foo本身不是数组,也不将数据保存在可以公开的类实例中;一种实现方法是让foo [19]返回一个结构,该结构包含对foo和值19的引用,并具有成员属性x,该成员属性可以调用“ foo.SetXValue(19,9) ;“这样的结构可以具有转换运算符,以将自身转换为“表观”类型的foo [19]。


在这两种情况下,将方法或属性返回的值存储到变量中,然后多次使用它会导致奇怪的行为。如果希望公开此类方法或属性的类的设计人员可以确保调用者不能多次使用它们,则将是理想的。有什么实际的方法可以做到这一点?

附录

在提出问题时,有时很难在复杂的用例和不太重要的简单用例之间划清界线。这是另一种用例,它与我最感兴趣的用例更接近(尽管我也对Fluent链感兴趣;能够像C ++那样对值类型进行引用会很不错,但可能也是如此)繁琐的工作)。

我有一个类似于Windows注册表的类型,它是项的层次结构集合,每个项都可以具有字符串值,整数值和/或嵌套的项集合。我希望能够支持以下类型的用法:

//将“ George”作为字符串存储在MyCollection中!哇
MyCollection [“ Wow”]。st =“乔治”
//将“ George”作为字符串存储在MyCollection中!
MyCollection [“ This”] [“ That”]。i = 9
//如果集合中不存在[“ Wow”],则引发异常
someInteger = MyCollection [“ This”] [“ That”]。i
//如果集合中不存在[“ This”] [“ That”],则引发异常
someString = MyCollection [“ Wow”]。st
//如果不存在,请使用9作为默认值
someInteger = MyCollection [“ Whatever”]。ii(9)
//如果不存在,则默认使用“乔治”
someString = MyCollection [“ Multi”] [“ Level”] [“ Path”]。sst(“ George”)


能够直接索引事物非常好(实际代码在VB中,因此可以使用“!”语法,无论好坏,这都是另一回事了)。在评估如下语句时:
MyCollection [“ This”] [“ that”]。st =“ George”或

someString = MyCollection [“ This”] [“ that”]。sst(“ George”)

必须为MyCollection [“ This”]返回某种类型的对象,而不知道该对象最终将用于读取还是写入。在后一种情况下,如果MyCollection [“ This”]不存在,则需要创建它。我目前的代码只是简单地创建了该节点,但是随后试图跟踪它是否“确实”存在,这最终成为了麻烦。这些对象中的许多对象都是深层克隆的,因此非常希望写入时复制,但是即使读取数据结构也可以更改它,写入时复制最终还是不切实际的。

一种更干净的解决方案是使索引器返回一个数据结构,该结构指示正在索引的集合和键值,然后对它最终进行任何操作(例如“ st”)以完成所有必要的索引。这将改善嵌套集合提供的抽象性,并且还将简化诸如写时复制的操作。一个警告是,如果有人要执行以下操作:

MyEvilVariable = MyCollection [“ This”];
MyEvilVariable [“ Nasty1”]。st =“我很邪恶”
MyEvilVariable [“ Nasty2”]。st =“真的很邪恶”


MyEvilVariable的第二次使用可能会破坏集合。

至于Fluent接口,我的想法是让WithXXX属性返回一个派生类的新实例,该实例用简单修改当前实例的版本来遮盖(而不是覆盖!)WithXXX属性。 WithXXX的返回对象将是派生类的,因此将使用带阴影的WithXXX方法,但是一旦将其分配给变量,它将被视为基类的实例,因此下一个WithXXX将创建一个新实例。

与C#或vb.net相比,C ++对值类型的概念更强,其中包括对值类型的引用非常有用的概念;它确保了对值类型的引用不能持久存在于所讨论类型的范围之外。 C#中的不安全代码可以使用指向值类型的指针,但是它们没有C ++引用提供的保护。

最佳答案

我认为没有。如果有的话,我将永远不会使用这种语言的滥用。


如果WithXYZ(int,int,int)存在,可能会更加高效。更好的是,不要担心这种效率,除非您已将其视为一个重要问题。
不要尝试通过“不错的”语法混淆事物。照原样对待事物,每个人的整体困惑就更少了。

关于c# - 类如何防止外部代码声明其类型的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4610664/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com