首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >你能推荐一个推荐人吗?

你能推荐一个推荐人吗?
EN

Stack Overflow用户
提问于 2013-06-10 13:19:03
回答 2查看 137关注 0票数 2

你能传递一个引用到一个引用类,比如传递一个控件的行为?

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

例如..。

代码语言:javascript
运行
复制
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的行为,如果是这样的话,你将如何构造一个与Control完全相同的int,以便当您将int赋值给int (如Control )时,它会像更改原始Control一样更改原始int。

这是可行的。send与Send相同。

代码语言:javascript
运行
复制
    new InputBox(((Label)sender)).ShowDialog();

    Label Send;
    public InputBox(Label send)
    {
     Send=send; 
    }

我想让它以同样的方式工作。Send现在与send相同,但不完全相同。

代码语言:javascript
运行
复制
    new InputBox(((string)sender)).ShowDialog();

    string Send;
    public InputBox(string send)
    {
     Send=send; 
    }

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-10 14:11:38

我认为,.NET中字符串的不变性会让您感到困惑。

字符串is a reference type。

但是它被设计成不可变的

这意味着,您的不能修改System.String实例。每次你做任何应该修改字符串的操作,它都会创建一个新的字符串的实例。请看下面的示例:

代码语言:javascript
运行
复制
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类。

票数 2
EN

Stack Overflow用户

发布于 2013-06-10 13:25:35

我认为你需要理解的是Value Types and Reference Types

值类型

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

它们包括以下类型

  • 所有数字数据类型
  • Boolean、Char和Date
  • 所有结构,即使它们的成员是引用类型,因为它们的基础类型始终是SByte、Short、Integer、Long、Byte、UShort、UInteger或ULong

鉴于

引用类型

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

它们包括以下类型

  • String
  • All数组,即使它们的元素是Form
  • Delegates

  • 类类型的值类型

所以离ref (C# Reference)更远

关键字ref使参数通过引用传递,而不是通过值传递。通过引用传递的效果是,对方法中的参数所做的任何更改都会反映在调用方法的基础实参变量中。

这就解释了为什么如果您希望将值类型propogate的更改更改为collung方法,则需要将方法符号更改为使用ref。

下面是一个关于构造函数调用的示例

代码语言:javascript
运行
复制
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();
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17017295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档