你能提供参考资料吗?

本文关键字:参考资料 | 更新日期: 2023-09-27 18:17:51

你能把一个引用传递给一个引用吗?

我注意到当你将一个控件传递给构造函数时,它实际上传递了一个对该控件的引用,然后如果你将另一个控件分配给该控件,它不是复制值,而是复制引用本身!为什么不能用常规变量或ref关键字来完成呢?

例如…

public class Test : Form
{
Test()
{
InitializeComponent();
}
Test_Load(object sender, EventArgs e)
{
new Test2((Control)MyTextBox).ShowDialog();
}
}
public class Test2 : Form
{
Public Control x_
Test2(Control x)
{
x_=x;
InitializeComponent();
}
//use x_ somewhere in code to actually change x
}

我不明白的是这对控件有效,但对其他变量无效。现在假设我把x作为一个int ref传递,我就不能把ref本身传递给x_吗?在控件的情况下,我甚至不必使用ref,这让我感到困惑,因为这究竟是如何发生的……我知道如何通过方法和父/所有者来回传递变量,所以我的问题非常具体到这个特定的准指针。也许我误解了传递控件的行为,如果是这种情况,你如何构造一个完全像Control一样的int,以便当你将一个int赋值给一个像Control一样的int时,它会改变原始int,就像它改变原始Control一样。

这工作。Send和Send是一样的

    new InputBox(((Label)sender)).ShowDialog();
    Label Send;
    public InputBox(Label send)
    {
     Send=send; 
    }

我希望这个以同样的方式工作。Send现在与Send相同,但不完全相同。

    new InputBox(((string)sender)).ShowDialog();
    string Send;
    public InputBox(string send)
    {
     Send=send; 
    }

我知道如何在类和这样的变量之间传递变量,但我要求特别有一个字符串的行为方式与Label传递时的行为方式相同。当它被传递时,它就像指针一样被传递,因为我可以让一个变量等于这个变量的相同实例。为什么我不能让一个字符串等于那个字符串的相同实例?

你能提供参考资料吗?

我认为你需要理解的是值类型和引用类型的区别

值类型

如果数据类型将数据保存在自己的内存中,则该数据类型是值类型分配。

包括

类型
  • 所有数值数据类型
  • 布尔值、字符和日期
  • 所有结构体,即使其成员是引用类型
  • 枚举,因为它们的底层类型总是SByte、Short、Integer、Long、Byte、UShort、UInteger或ULong

引用类型

引用类型包含一个指向另一个内存位置的指针保存数据

它们包括

类型
    字符串
  • 所有数组,即使它们的元素是值类型
  • 类类型,如Form
  • 代表

因此进一步从ref (c# Reference)

ref关键字导致参数通过引用传递,而不是通过价值。通过引用传递的效果是,对参数反映在基础实参中

这就解释了为什么如果您希望将对值类型的更改传递给collung方法,则需要将方法签名更改为使用ref。

下面是一个关于构造函数调用 的例子
Control c1 = null;
Class1 cl1 = new Class1(c1); //c1 is still null after this call
Control c2 = null;
Class1 cl2 = new Class1(ref c2); //c2 is NOT null after this call
class Class1
{
    public Class1(Control c)
    {
        c = new Control();
    }
    public Class1(ref Control c)
    {
        c = new Control();
    }
}

我想,. net中字符串的不可变性是一件让你困惑的事情。

字符串是引用类型。
但是它被设计成不可变的

这意味着不能修改System.String实例。每次你做任何应该修改string的操作时,它都会创建一个string的新实例。看看这个例子:

class A
{
    private string someString;
    public A(string someString)
    {
        this.someString = someString;
    }
    public string SomeString
    {
        get { return someString; }
    }
    public void DoSomething()
    {
        someString = someString + "_abc";
    }
}

var sampleString = "Hello, world!";
var a = new A(sampleString);
Console.WriteLine(a.SomeString == sampleString); // prints 'true'
a.DoSomething();
Console.WriteLine(a.SomeString == sampleString); // prints 'false'
Console.WriteLine(sampleString); // prints 'Hello, world!'
Console.WriteLine(a.SomeString); // prints 'Hello, world!_abc'

初始sampleStringA.someString相等。

但是在someString = someString + "_abc"这行之后,字段A.someString引用了另一个 string实例,因为+操作符创建了一个新的实例,并且赋值操作符将该实例赋值给了A.someString

System.String不能像Label一样,因为Label是可变的。因此,Label.Text = "Foobar";不会创建label的新实例。

乌利希期刊指南。如果你想要一个可变字符串,它已经在FCL中出现了。这是StringBuilder