C# 在C中指定这个关键字#
主要问题是,允许修改this关键字对有用性和记忆有什么影响;为什么C语言规范中允许这样做 如果选择回答,则可以回答或不回答其他问题/子部分。我认为对这些问题的回答将有助于澄清主要问题的答案 我无意中发现了这一点,以此作为回答 我一直在想为什么C语言规范会允许这样做子部分1。是否有任何东西可以证明此是可修改的?它有用吗 对该答案的评论之一是 从CLR通过C#:他们这样做的原因是因为你 可以在另一个结构中调用结构的无参数构造函数 构造器。如果只想初始化结构的一个值 如果希望其他值为零/空(默认值),则可以编写public Foo(intbar){this=newfoo();specialVar=bar;}。这不是 高效且不真正合理(specialVar分配两次),但 仅供参考。(这是书中给出的理由,我不知道我们为什么 不应该只做公共Foo(int-bar):this()) 第2部分。我不确定我是否遵循了这个推理。有人能澄清他的意思吗?也许是如何使用它的一个具体例子 编辑(忽略堆栈或堆的要点与内存释放或垃圾回收有关。可以用262144个公共int字段替换int[]而不是int[] 根据我的理解,如果这个结构有一个1 Mb字节的数组字段,那么结构是在堆栈上创建的,而不是在堆上创建的C# 在C中指定这个关键字#,c#,.net,memory,specifications,C#,.net,Memory,Specifications,主要问题是,允许修改this关键字对有用性和记忆有什么影响;为什么C语言规范中允许这样做 如果选择回答,则可以回答或不回答其他问题/子部分。我认为对这些问题的回答将有助于澄清主要问题的答案 我无意中发现了这一点,以此作为回答 我一直在想为什么C语言规范会允许这样做子部分1。是否有任何东西可以证明此是可修改的?它有用吗 对该答案的评论之一是 从CLR通过C#:他们这样做的原因是因为你 可以在另一个结构中调用结构的无参数构造函数 构造器。如果只想初始化结构的一个值 如果希望其他值为零/空(默认值),
public int[] Mb = new int[262144];
第3子部分。调用Foo时是否会将其从堆栈中删除?在我看来,由于结构从未超出范围,因此它不会从堆栈中删除。今晚没有时间创建一个测试用例,但也许明天我会为这个做准备
在下面的代码中
Teaser t1 = new Teaser();
Teaser tPlaceHolder = t1;
t1.Foo();
子部分4。t1和tPlaceHolder是否占用相同或不同的地址空间
很抱歉提出一个3年前的帖子,但这篇帖子真的让我头疼
仅供参考,关于stackoverflow的第一个问题,所以如果我在这个问题上有什么问题,请发表评论,我将进行编辑
两天后,我将在这个问题上悬赏50英镑,即使我已经在脑海中选择了一个获胜者,因为我认为答案需要合理的工作量来解释这些问题 具有此可分配性允许使用结构的“高级”角落案例。我发现的一个例子是交换方法:
struct Foo
{
void Swap(ref Foo other)
{
Foo temp = this;
this = other;
other = temp;
}
}
我强烈反对这种用法,因为它违反了结构的默认“期望”性质,即不可变性。可以说,有这一选择的原因尚不清楚
现在,当涉及到结构本身时。它们在以下几个方面与班级不同:
- 它们可以存在于堆栈上,而不是托管堆上
- 它们可以封送回非托管代码
- 不能将它们分配给空值
// declare 2 references to instances on the managed heap
var c1 = new MyClass();
var c2 = new MyClass();
// declare 2 labels to instances on the stack
var s1 = new MyStruct();
var s2 = new MyStruct();
c1 = c2; // copies the reference data which is the pointer internally, c1 and c2 both point to the same instance
s1 = s2; // copies the data which is the struct internally, c1 and c2 both point to their own instance with the same data
首先,我认为你应该先检查一下你问的问题是否正确。也许我们应该问,“为什么C#不允许在结构中对
这个赋值?”
在引用类型中指定this
关键字有潜在危险:您正在覆盖对正在运行的对象方法的引用;您甚至可以在初始化该引用的构造函数中这样做。现在还不清楚这种行为应该是什么。为了避免必须弄清楚这一点,因为它通常没有用处,所以规范(或编译器)不允许这样做
但是,在值类型中为这个
关键字赋值是有明确定义的。赋值类型是一种复制操作。每个字段的值从赋值的右侧到左侧递归复制。这是一次非常安全的手术
// declare 2 references to instances on the managed heap
var c1 = new MyClass();
var c2 = new MyClass();
// declare 2 labels to instances on the stack
var s1 = new MyStruct();
var s2 = new MyStruct();
c1 = c2; // copies the reference data which is the pointer internally, c1 and c2 both point to the same instance
s1 = s2; // copies the data which is the struct internally, c1 and c2 both point to their own instance with the same data
Teaser t1 = new Teaser();
Teaser tPlaceHolder = t1;
t1.Foo();
public struct Foo
{
// Fields etc here.
public Foo(int a)
{
this = new Foo();
this.a = a;
}
}
public void SwapValues(MyStruct other)
{
var temp = other;
other = this;
this = temp;
}
public struct ImmutableData
{
private readonly int data;
private readonly string name;
public ImmutableData(int data, string name)
{
this.data = data;
this.name = name;
}
public int Data { get => data; }
public string Name { get => name; }
public void SetName(string newName)
{
// this wont work
// this.name = name;
// but this will
this = new ImmutableData(this.data, newName);
}
public override string ToString() => $"Data={data}, Name={name}";
}
class Program
{
static void Main(string[] args)
{
var X = new ImmutableData(100, "Jane");
X.SetName("Anne");
Debug.WriteLine(X);
// "Data=100, Name=Anne"
}
}
public void ReadXml(XmlReader reader)
{
var data = int.Parse(reader.GetAttribute("Data"));
var name = reader.GetAttribute("Name");
this = new ImmutableData(data, name);
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("Data", data.ToString());
writer.WriteAttributeString("Name", name);
}
<?xml version="1.0" encoding="utf-8"?>
<ImmutableData Data="100" Name="Anne" />
var xs = new XmlSerializer(typeof(ImmutableData));
var fs = File.OpenText("Store.xml");
var Y = (ImmutableData)xs.Deserialize(fs);
fs.Close();