C# 中的自动生存
尝试着理解 Perl 的 Autovivification,根据它的听起来,它的工作原理似乎与 C# 中的动态类似,因为动态对象直到运行时才被分配类型,或者,我完全不在这吗?如果是这样,那么是否有一个类似的想法可以在 C# 中桥接,这是有意义的?
编辑
好吧,看来我还差得很远。那么,作为两部分问题的第二部分,C# 中是否存在概念上可比的内容?需要明确的是,我正在 C# 中寻找一个与 Autovivification 类似的概念。不必完全相同,但在概念上足够接近才能有意义。正如我之前所说,我绝不是一个 Perl 黑客或 Python 黑客,但是,我熟悉基于 C 的语言 C、C++、C#、java、javascript。我正在考虑 C# 的动态,但是,截至目前,我正在考虑基于此处信息的延迟加载(如果有帮助的话)。
Trying to wrap my head around perl's Autovivification and based on what it sounds like, It seems to work similar to dynamics in C# as a dynamic object is not assigned a type until runtime or, am I totally off here. If so then is there a comparable idea that I can bridge off of in C# that makes sense?
Edit
Okay so I'm apparently way off. So as second part of the 2 part question, is there anything conceptually comparable in C#? To be clear I'm looking for a concept in C# that is comparable to Autovivification. Doesn't have to be exactly the same but close enough conceptually to make sense. And as I stated eariler I am by no means a perl hacker or python hacker by any stretch of the imagination but, I am familar with c based languages C, C++, C#, java, javascript. I was thinking of C#'s dynamics but, as of right now I'm thinking lazy loading based on the info here if that helps....
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我无法用 C# 说话,但用外行人的话来说,Perl 的自动生存是在需要时立即从未定义的值创建容器对象的过程。
尽管大多数 Perl 相当动态,但 Perl 的取消引用语法在编译时明确指定了引用的类型。这使得解释器可以在定义变量之前知道它需要从变量中得到什么。
这个列表可能会更长,但应该可以给您一个想法。
所以基本上,当你有这样的行时:
Perl 查看
->
的右侧并看到方括号。这意味着调用者$var
必须是数组引用。由于调用者未定义,Perl 创建一个新数组并将其引用安装到$var
中。然后,对于每个后续解除引用,都会重复相同的过程。所以上面这行的真正意思是:
这是相当可怕的,因此是自动生存。 (
//=
是perl 5.10+中定义的或赋值运算符)更新:
根据cjm的评论,将其放入一般非perl术语中,以实现自动生存在另一种语言中,您需要一个支持通过
[...]
和{...}
进行索引的惰性对象。当执行这些索引操作中的任何一个时,对象都会用数组或散列替换自身。每次访问该对象时,如果单元格为空,则应返回另一个惰性对象。所以基本上你需要两件事,创建一个支持数组和散列下标(或等效项)索引的对象的能力,以及一种机制,使对象可以在内存中用另一个对象替换自己(或者可以将自己锁定到一种解释,然后在内部存储新对象,
可以从以下伪代码开始:
I can't speak to C#, but in layman's terms, Perl's autovivification is the process of creating a container object out of an undefined value as soon as it is needed.
Despite most of Perl being quite dynamic, Perl's dereferencing syntax unambiguously specifies the type of the reference at compile time. This allows the interpreter to know what it needs out of a variable before the variable is ever defined.
This list could be longer, but should give you an idea.
So basically, when you have a line like this:
Perl looks on the right side of the
->
and sees square braces. This means that the invocant$var
must be an array reference. Since the invocant is undefined, Perl creates a new array and installs its reference into$var
. This same process is then repeated for every subsequent dereferencing.So the line above really means:
which is fairly hideous, and hence autovivification. (
//=
is the defined-or assignment operator in perl 5.10+)Update:
As per cjm's comment, to put this into general non-perl terms, to achieve autovivification in another language, you need a lazy object that supports indexing via
[...]
and{...}
. When either of these indexing operations are performed, the object replaces itself with either an array or hash. Every time the object is then accessed, if the cell is empty, it should return another lazy object.So basically you need two things, the ability to create an object that supports indexing with both array and hash subscripts (or the equivalent), and a mechanism such that an object can replace itself in memory with another object (or that can lock itself to one interpretation, and then store the new object internally.
Something like the following pseudo-code could be a start:
Uri Guttman 的 自动生存教程 可能会有一些用处。
基本上,它是迄今为止未受影响的聚合体和聚合体成员在第一次使用时复活的能力。
例如,我可以这样做:
$dummy[0]
和$dummy[1]
在取消引用之前都不存在。现在,如果您愿意放弃
strict
(您不应该这样做),您还可以执行以下操作:未定义的变量
$x
成为数组引用因为它正在被取消引用。Uri Guttman's autovivification tutorial might be of some use.
Basically, it is the ability of hitherto untouched aggregates and members of aggregates to spring to life upon first use.
For example, I can do this:
Neither
$dummy[0]
nor$dummy[1]
exist before they are dereferenced.Now, if you are willing to forgo
strict
(which, you shouldn't be), you can also do things like:whereby the undefined variable
$x
becomes an array reference because it is being dereferenced as such.您可以通过创建一个
IDictionary
来实现类似自动验证的行为,它返回(并存储)一个新的IDictionary
(例如,递归地相同类型)当发生未设置键的[]
时。这种方法在 Ruby 中的使用取得了巨大成功(一个示例)——然而,事实并非如此在静态类型语言中如此有用,因为没有办法干净地“获取”叶子值——至少在大多数现有合约(例如 IDictionary)的上下文中是这样。随着
dynamic
的出现,这在 C# 中可能可以正常完成,但我不知道。You can implement autovification-like behavior with creating say, an
IDictionary<X,Y>
that returns (and stores) a newIDictionary<X,Y>
(e.g. recursively the same type) when a[]
to an unset key occurs. This approach is used in Ruby to great success (an example) -- however, it's really not so useful in a statically typed language because there is no way to "get to" the leaf values cleanly -- at least in context of most existing contracts such as anIDictionary
.With the advent of
dynamic
, this may be possible in C# to do sanely, but I do not know.对于 C# 中字典的自动激活行为的简单实现,像这样的东西怎么样?显然这并不像 Perl 那样处理它,但我相信它具有相同的效果。
How about something like this for a simple implementation of auto-vivification like behaviour of a Dictionary in C#? Obviously this doesn't handle it in the generic way that Perl does, but I believe that it has the same effect.
我建议使用扩展方法而不是继承。
例如:
I would recommend using extension methods instead of inheritance.
e.g.:
使用索引器和 C# 4.0 动态,
DynamicObject 也可用于实现不同的语法,
Using indexers and C# 4.0 dynamics,
DynamicObject can be used for implementing different syntaxes also,