SAFE Pointer to a pointer (well reference to a reference) in C#
在我正在开发的C应用程序中,我有一个非常长的标识符,如下所示:
1 | foo.bar.bwah.blah.whatever.very.very.huge |
每当我引用这个对象时,它绝对是一场噩梦,不幸的是,我确实需要大量引用它:
1 2 3 | var something = foo.bar.bwah.blah.whatever.very.very.huge.a; var somethingElse = foo.bar.bwah.blah.whatever.very.very.huge.b; foo.bar.bwah.blah.whatever.very.very.huge.c = 12; |
等。
我希望使用某种更小的别名来更新此代码,但是问题是我希望更改基础引用,并且在不显式更新别名的情况下更新别名。
目前,如果我执行以下操作:
1 2 3 4 | foo.bar.bwah.blah.whatever.very.very.huge.a ="hello"; string shorter = foo.bar.bwah.blah.whatever.very.very.huge.a; foo.bar.bwah.blah.whatever.very.very.huge.a ="world"; Console.WriteLine(shorter); |
它将输出"你好"。我想要达到的目标是:
1 2 3 4 | foo.bar.bwah.blah.whatever.very.very.huge.a ="hello"; string** shorterPointer = &foo.bar.bwah.blah.whatever.very.very.huge.a; foo.bar.bwah.blah.whatever.very.very.huge.a ="world"; Console.WriteLine(**shorter); |
根据需要输出"世界"。
我相信使用C中的不安全代码可以实现类似的效果,但是我不能这样做,我只能使用安全代码。
有人知道我怎样才能做到这一点吗?
请注意:这个问题不是关于字符串是不可变的,我知道它们是-事实上,我假设它们是为了这个问题。如果我用其他类型的…因此,当我将"hello"分配给一个当时的"world"时,我每次都在实例化不同的对象,因此,我存储的对a的引用在重新分配后变为无效。
一种方法是使用一只或一对羊羔。
例如:
1 2 | Func<string> getter = () => blah_de_blah; Action<string> setter = x => blah_de_blah = x; |
现在,您可以使用getter和setter来读写长标识符。
但是,由于您的点是成员访问器,最简单的方法是引用直接父对象,如:
1 2 | var myHuge = foo.bar.bwah.blah.whatever.very.very.huge; // now access myHuge.a everywhere |
在任何情况下,这都是很好的做法,因为这样一个长点的表达式违反了德米特定律,这抑制了代码库的灵活性——它在太多的地方需要太多的信息。
我将使用名称空间别名。
1 | using myAlias = foo.bar.bwah.blah.whatever.very.very |
然后在你的方法中,你只需要输入:
第一件事。我会重新考虑你的建筑。这似乎太复杂了!:)
不管怎样,我们开始谈正事吧。
字符串在.NET中是不可变的,这就是您的问题。当您更改对象的属性时,您将在内存上创建一个新的字符串,并用对象的属性指向该字符串。但是,这不会改变字符串变量(为什么要这样做?)。变量没有更改,因此它一直指向上一个字符串。
这就是问题所在,现在讨论解决方案。我建议创建对包含字符串的对象的引用,仅高于一个级别,如下所示:foo.bar.bwah.blah.whatever.very.very.hurge.a="你好";巨大的=foo.bar.bwah.blah.whatever.very.very.large;巨大的。A ="嘘!";
希望它有帮助!:)