【问题标题】:SAFE Pointer to a pointer (well reference to a reference) in C#指向 C# 中的指针(以及对引用的引用)的安全指针
【发布时间】:2008-11-26 11:46:08
【问题描述】:

在我正在处理的 C# 应用程序中,我有一个很长的标识符,如下所示:-

foo.bar.bwah.blah.whatever.very.very.huge

每当我引用这个对象时,这绝对是一场噩梦,不幸的是我确实需要大量引用它:-

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;

等等。等等

我想使用某种更小的别名来更新此代码,但问题是我想更改底层引用,并且还更新别名而不显式更新别名

目前,如果我执行以下操作:-

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);

它将输出“你好”。我想要实现的是以下内容:-

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”分配给a然后将“world”分配给a时,我每次都实例化不同的对象,因此我存储了引用to a 重新分配后失效。

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    一种方法是使用一个或一对 lambda。

    例如:

    Func<string> getter = () => blah_de_blah;
    Action<string> setter = x => blah_de_blah = x;
    

    现在,您可以使用 getter 和 setter 来读取和写入长标识符。

    但是,由于您的点是成员访问器,因此最简单的方法是引用直接父级,如下所示:

    var myHuge = foo.bar.bwah.blah.whatever.very.very.huge;
    // now access myHuge.a everywhere
    

    在任何情况下,这都是一种很好的做法,因为像这样的长点表达式违反了Law of Demeter,这会抑制代码库的灵活性——它需要在太多地方提供太多信息。

    【讨论】:

    • 巴里真是太好了,你绝对的救命稻草!
    • 如果是这样,那么您需要做的就是保持对巨大的引用,并取消引用以每次都获取“a”成员。
    • 巴里,如果我重新分配酒吧怎么办?那就不成立了。
    • 关于得墨忒耳定律的观点非常好,谢谢,将看看架构!
    • 如果你重新分配给 bar,那么你会破坏它,是的。但是,这也会破坏 lambda 方法 - 充其量,lambda 将捕获表达式的根(如果有,则为隐含的“this”,否则为“foo”)。重新分配 foo 的“bar”属性将以同样的方式破坏引用。
    【解决方案2】:

    我会使用命名空间别名。

    using myAlias = foo.bar.bwah.blah.whatever.very.very
    

    然后在你的方法中你只需要输入:myAlias.huge.a = "hello";

    【讨论】:

    • using语句不就是单纯的类型别名吗?
    • 您只能使用 using 定义命名空间。由于提出的问题是一长串代码,我想这会起作用;)
    【解决方案3】:

    第一件事。我会重新考虑你的架构。这似乎太复杂了! :)

    不管怎样,让我们​​开始吧。

    字符串在 .NET 中是不可变的,这是您的问题。当您更改对象的属性时,您将在内存上创建一个新字符串并使用对象的属性指向那里。但是,这不会更改您的字符串变量(为什么要这样做?)。变量没有改变,所以它一直指向前一个字符串。

    这就是问题所在,现在来解决。我建议创建对包含字符串的对象的引用,就在上一级,如下所示: foo.bar.bwah.blah.whatever.very.very.huge.a = "你好"; 巨大巨大 = foo.bar.bwah.blah.whatever.very.very.huge; 巨大的.a = "foo!";

    希望对您有所帮助! :)

    【讨论】:

    • 首先,这与字符串无关,我使用该示例假设字符串是不可变的,这样我可以更清楚地说明我的观点!那也许不是最好的选择! :-) 是的,但是如果我想重新分配“巨大”对象怎么办?如果说 bwah 被重新分配,我们也会出错。
    • 哦,我不认为这是架构问题!虽然也许它可以更好地构建;实际代码只有 3-4 个字段深,只是名称比较长。我认为这个问题很可能出现在结构良好的架构中。
    • 我看到了克罗诺兹,这是真的。现在我明白你的意思了。但是,我认为仅仅为了编写较短的名称而使代码过于复杂是不值得的。但也许这只是我!不管怎样,这个问题很有趣,我会关注它,如果我想出什么,我会再次发布!
    猜你喜欢
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 2010-12-26
    相关资源
    最近更新 更多