gpt4 book ai didi

c# - 像这样标记对象是合法代码吗?

转载 作者:行者123 更新时间:2023-11-30 21:41:32 26 4
gpt4 key购买 nike

我曾经写过一篇 code to add a name to a Task .下面的代码似乎做同样的事情,但代码更少。但我想知道,这是合法的。生产代码准备好了吗?垃圾回收呢?如果在代码中移动类的实例(因为它没有被固定),它在移动时是否仍然有效?如何测试此代码?

using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var obj = new object();
obj.Tag("Link some data");
var tag = obj.Tag();
}
}

public static class ObjectExtensions
{
private class Tagger
{
public string Tag { get; set; }
}

[StructLayout(LayoutKind.Explicit)]
private struct Overlay
{
[FieldOffset(0)]
public Tagger Tagger;
[FieldOffset(0)]
public object Instance;
}

public static string Tag(this object obj)
{
var overlay = new Overlay {Instance = obj };
return overlay.Tagger.Tag;
}

public static void Tag(this object obj, string tag)
{
var overlay = new Overlay {Instance = obj };
overlay.Tagger.Tag = tag;
}
}
}

最佳答案

不,这根本不合法。坦率地说,令我惊讶的是 .NET 和 C# 允许在没有 /unsafe 开关的情况下这样做。你的提议有明显的风险,但我不得不承认,在使用 C# 编写代码的这些年里,我从未想过有人能够像这样在 C# 中违反安全内存访问,而无需显式启用不安全代码。

考虑你的例子的这种变化:

class A
{
public string Text { get; set; }
}

class Program
{
static void Main(string[] args)
{
A a = new A { Text = "Text" };

a.Tag("object A tag");

string tag = a.Tag(), text = a.Text;
}
}

您会发现,在最后一条语句中,text 变量已设置为"object A Tag"。换句话说,您的“覆盖”方法允许您的代码将对类 A 的对象的引用重新解释为对类 Overlay 的对象的引用,而无需任何某种编译器警告或运行时错误。

在上面的示例中,结果与您希望的一样好:Text 的原始属性值已从其正确值更改为作为“标签”传递的文本。这已经够糟糕了,但在其他情况下,您可能会发现您的类已以可怕的方式损坏,导致进一步的数据损坏或(如果幸运的话)由于某种访问冲突或其他异常而导致您的程序立即终止.

不要这样做。这是非常危险的,当然,当按照您在此处建议的方式使用时,永远 不会正常工作。你总是会覆盖一些你不应该拥有的数据。

关于c# - 像这样标记对象是合法代码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43285698/

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