有关.net编程的几点困惑 你用c++的思考方法,去考虑.net了! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 static void Trans(ref object obj){};调用: xxx.Trans(ref obj); to xz_king(西杀魄工人) 我没看明白。我觉得我现在就是引用调用 我想要的是一种类似于传值的调用效果。还有一点更重要的就是,是不是我想要的这种写法在.net里就是一种错误的想法。而string 不过就是一个特例 也许是这样来,能简单达到你的目的,但解决不了你的迷惑(你的1,2说的都对,我也在迷惑呢…)public static void Main(String[] args) { c1 c; c = new c1(); Console.WriteLine("{0}",c.a); f(new c1(c)); Console.WriteLine("{0}",c.a); } 你可以考虑为class c1增加一个公共属性:public c1 MemObject{ get { return new c1(this); } set { this.a = value.a; }}客户端代码:c1 c;c = new c1();Console.WriteLine("{0}",c.a);c1 memObject = c.MemObject; <<===f(c);Console.WriteLine("{0}",c.a);c.MemObject = memObject; <<===Console.WriteLine("{0}",c.a); 我在怀疑,是不是,我的设计想法有问题,.net里就不会出现这种设计 解决的方法,肯定很多,我在函数的入口处,加上一个Clone(),应该也可以,但是我想知道的就是,实现的机制,还有,就是这样设计合不合理,在c++里加一个拷贝构造函数,就可以了,这也是标准的解决办法,但是,在.net里呢,还是根本不需要解决,因为就不要让它出现 我指的机制是相string那样,外面并没有做任何操作,完全是由类自己完成的 string确实比较特殊,如class Class1 { [STAThread] static void Main(string[] args) { string s="1234"; Console.WriteLine(s);//输入1234 Change(s); Console.WriteLine(s);//输入1234 Console.ReadLine(); } public static void Change(string s) { s="changed!"; Console.WriteLine(s);//changed! } }因为在Change方法中;执行s="changed!";时实质是.net CLR构造一个新的字符串"changed!",并将s指向这个新生成的字符串的新的地址(在托管堆中)。这大概和CLR的特别处理有关吧!所以到达了向传值一样的效果。问题是内部具体是怎样处理的呢,我们自己写的类可以做到这样吗? 这个问题确实值得研究。 to jjcccc() : 你的说法对我有了些启发,如果按你的说法,那么实际上在Change(string s)的时候,string和其他的没有区别,而这真正关键的是s="changed!";这句,这句让函数里的s和外面的s有了区分,成为两个变量,如果是这样的话,那么我的两个问题,可能可以归结为一个,就是怎样重载的= 不知道我的想法对不对,也许有问题 我现在还搞不清string的这种特性是在函数传值是就表现出来了,还是像我上面说的,只是在赋值时才有 这是我上面例子的反汇编后的代码,正在琢磨...,好像有点感觉:method /*06000001*/ private hidebysig static void Main(string[] args) cil managed{ .entrypoint .custom /*0C000001:0A00000E*/ instance void [mscorlib/* 23000001 */]System.STAThreadAttribute/* 0100000F */::.ctor() /* 0A00000E */ = ( 01 00 00 00 ) // Code size 31 (0x1f) .maxstack 1 .locals /*11000001*/ init ([0] string s) .language '{3F5162F8-07C6-11D3-9053-00C04FA302A1}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'// Source File 'f:\mystudio\c#\consoleapplication5\class1.cs' //000016: string s="1234"; IL_0000: ldstr "1234" /* 70000001 */ IL_0005: stloc.0//000017: Console.WriteLine(s); IL_0006: ldloc.0 IL_0007: call void [mscorlib/* 23000001 */]System.Console/* 01000010 */::WriteLine(string) /* 0A00000F *///000018: //000019: Change(s); IL_000c: ldloc.0 IL_000d: call void ConsoleApplication5.Class1/* 02000002 */::Change(string) /* 06000002 *///000020: //000021: Console.WriteLine(s); IL_0012: ldloc.0 IL_0013: call void [mscorlib/* 23000001 */]System.Console/* 01000010 */::WriteLine(string) /* 0A00000F *///000022: //000023: Console.ReadLine(); IL_0018: call string [mscorlib/* 23000001 */]System.Console/* 01000010 */::ReadLine() /* 0A000010 */ IL_001d: pop//000024: //000025: //000026: } IL_001e: ret} // end of method Class1::Main.method /*06000002*/ public hidebysig static void Change(string s) cil managed{ // Code size 14 (0xe) .maxstack 1 .language '{3F5162F8-07C6-11D3-9053-00C04FA302A1}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'// Source File 'f:\mystudio\c#\consoleapplication5\class1.cs' //000030: s="changed!"; IL_0000: ldstr "changed!" /* 7000000B */ IL_0005: starg.s s//000031: Console.WriteLine(s); IL_0007: ldarg.0 IL_0008: call void [mscorlib/* 23000001 */]System.Console/* 01000010 */::WriteLine(string) /* 0A00000F *///000032: } IL_000d: ret} // end of method Class1::Change 比较一下楼主的void f(c1 c)方法的汇编代码:.method /*06000003*/ public hidebysig static void f(class TestRef.c1/* 02000002 */ c) cil managed{ // Code size 9 (0x9) .maxstack 2 .language '{3F5162F8-07C6-11D3-9053-00C04FA302A1}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'// Source File 'f:\mystudio\c#\consoleapplication6\class1.cs' //000025: c.a = 20; IL_0000: ldarg.0 IL_0001: ldc.i4.s 20//下面这句就是不同的地方,对字符串用的是 starg.s s//将堆栈中的值复制到s中 IL_0003: stfld int32 TestRef.c1/* 02000002 */::a /* 04000001 *///000026: } IL_0008: ret} // end of method TestRef::f 那么,现在,可以肯定的一点是,第一个问题实际上并不存在,string用的还是引用传值,关键是在赋值操作上,但是,汇编代码看,并不像对=进行了重载 你说的很对,可能是在编译阶段就对string进行了特别处理!? 对DataGridView中的数据进行新增和修改,怎么做才是最方便的? 可以把字符串中的每个单词加上双引号. dropdownbutton(也是一种按钮,不过在按钮右边有下拉箭头可以点出列表的)控件如何开发使用 如何在两个Access数据库的两个表之间创建查询? 如何遍历目录下所有文件夹,并给文件夹改名? 应该程序;怎么防止打多个相同的窗口啊? 急!... 手机彩信开发须知?? 你肯定遇到过这样的错误提示 一个可怕的问题。 我删掉了有关于《C#必败》的贴子 哪位能提供VS.NET中的IE控件的使用帮助文档? 散分
我没看明白。我觉得我现在就是引用调用
我想要的是一种类似于传值的调用效果。还有一点更重要的就是,是不是我想要的这种写法在.net里就是一种错误的想法。而string 不过就是一个特例
public static void Main(String[] args)
{
c1 c;
c = new c1();
Console.WriteLine("{0}",c.a);
f(new c1(c));
Console.WriteLine("{0}",c.a);
}
public c1 MemObject
{
get
{
return new c1(this);
}
set
{
this.a = value.a;
}
}客户端代码:
c1 c;
c = new c1();
Console.WriteLine("{0}",c.a);
c1 memObject = c.MemObject; <<===
f(c);
Console.WriteLine("{0}",c.a);
c.MemObject = memObject; <<===
Console.WriteLine("{0}",c.a);
{
[STAThread]
static void Main(string[] args)
{
string s="1234";
Console.WriteLine(s);//输入1234 Change(s); Console.WriteLine(s);//输入1234 Console.ReadLine();
} public static void Change(string s)
{
s="changed!";
Console.WriteLine(s);//changed!
}
}因为在Change方法中;执行s="changed!";时实质是.net CLR构造一个新的字符串"changed!",并将s指向这个新生成的字符串的新的地址(在托管堆中)。这大概和CLR的特别处理有关吧!所以到达了向传值一样的效果。问题是内部具体是怎样处理的呢,我们自己写的类可以做到这样吗?
这个问题确实值得研究。
你的说法对我有了些启发,如果按你的说法,那么实际上在Change(string s)的时候,string和其他的没有区别,而这真正关键的是s="changed!";这句,这句让函数里的s和外面的s有了区分,成为两个变量,如果是这样的话,那么我的两个问题,可能可以归结为一个,就是怎样重载的=
不知道我的想法对不对,也许有问题
method /*06000001*/ private hidebysig static
void Main(string[] args) cil managed
{
.entrypoint
.custom /*0C000001:0A00000E*/ instance void [mscorlib/* 23000001 */]System.STAThreadAttribute/* 0100000F */::.ctor() /* 0A00000E */ = ( 01 00 00 00 )
// Code size 31 (0x1f)
.maxstack 1
.locals /*11000001*/ init ([0] string s)
.language '{3F5162F8-07C6-11D3-9053-00C04FA302A1}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'
// Source File 'f:\mystudio\c#\consoleapplication5\class1.cs'
//000016: string s="1234";
IL_0000: ldstr "1234" /* 70000001 */
IL_0005: stloc.0
//000017: Console.WriteLine(s);
IL_0006: ldloc.0
IL_0007: call void [mscorlib/* 23000001 */]System.Console/* 01000010 */::WriteLine(string) /* 0A00000F */
//000018:
//000019: Change(s);
IL_000c: ldloc.0
IL_000d: call void ConsoleApplication5.Class1/* 02000002 */::Change(string) /* 06000002 */
//000020:
//000021: Console.WriteLine(s);
IL_0012: ldloc.0
IL_0013: call void [mscorlib/* 23000001 */]System.Console/* 01000010 */::WriteLine(string) /* 0A00000F */
//000022:
//000023: Console.ReadLine();
IL_0018: call string [mscorlib/* 23000001 */]System.Console/* 01000010 */::ReadLine() /* 0A000010 */
IL_001d: pop
//000024:
//000025:
//000026: }
IL_001e: ret
} // end of method Class1::Main.method /*06000002*/ public hidebysig static
void Change(string s) cil managed
{
// Code size 14 (0xe)
.maxstack 1
.language '{3F5162F8-07C6-11D3-9053-00C04FA302A1}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'
// Source File 'f:\mystudio\c#\consoleapplication5\class1.cs'
//000030: s="changed!";
IL_0000: ldstr "changed!" /* 7000000B */
IL_0005: starg.s s
//000031: Console.WriteLine(s);
IL_0007: ldarg.0
IL_0008: call void [mscorlib/* 23000001 */]System.Console/* 01000010 */::WriteLine(string) /* 0A00000F */
//000032: }
IL_000d: ret
} // end of method Class1::Change
void f(class TestRef.c1/* 02000002 */ c) cil managed
{
// Code size 9 (0x9)
.maxstack 2
.language '{3F5162F8-07C6-11D3-9053-00C04FA302A1}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'
// Source File 'f:\mystudio\c#\consoleapplication6\class1.cs' //000025: c.a = 20;
IL_0000: ldarg.0
IL_0001: ldc.i4.s 20//下面这句就是不同的地方,对字符串用的是 starg.s s//将堆栈中的值复制到s中
IL_0003: stfld int32 TestRef.c1/* 02000002 */::a /* 04000001 */
//000026: }
IL_0008: ret
} // end of method TestRef::f