C# 引用传递对象与cs1690之间的冲突
此代码已更新。 Robot.cs:C# 引用传递对象与cs1690之间的冲突,c#,object,ref,C#,Object,Ref,此代码已更新。 Robot.cs: struct state systemcheck() { state stateInfo = new state(); public double x,y,z; } Main.cs: public state stateInfo; private readonly Sub cpnew; public Main() { InitializeComponent(); cpnew = new Sub(this); } Sub.cs: public s
struct state systemcheck()
{
state stateInfo = new state();
public double x,y,z;
}
Main.cs:
public state stateInfo;
private readonly Sub cpnew;
public Main()
{
InitializeComponent();
cpnew = new Sub(this);
}
Sub.cs:
public state systinfo;
private readonly Main main;
public Sub(Main main)
{
InitializeComponent();
this.main = main;
systinfo = this.main.stateInfo;
}
这里,systinfo.X
提供了一个空值。但是mainfrm.stateInfo.X
提供了正确的值,但抛出了引用封送类警告。
初始化systinfo的正确方法是什么?
state
的值是从外部连接的机器人获得的 这是你要求的一件好事-记住,除非你完全知道自己在做什么,否则一定要遵守警告。在这种情况下,你肯定不知道自己在做什么
表单
是一个类
——所有类都是.NET中的引用类型。这有几个含义,其中一个在这里非常相关——它们总是通过引用传递。换句话说,当您使用Main
作为参数时,您已经在传递引用(类似于在C中传递指向Main
的指针)
使用ref
,将引用传递给引用。这允许您从方法内部修改外部引用。这不是您想要的-作为一个简单的示例,它允许您编写一个增量方法:
public void Increment(ref int value)
{
value = value + 1;
}
如果未使用ref
,则只需修改value
的本地值即可。使用ref
,它修改调用者中的本地值
在您的情况下,正确的代码将更接近
public state stateInfo;
private readonly Sub cpnew;
public Main()
{
InitializeComponent();
cpnew = new Sub(this);
}
表格2:
public state systinfo;
private readonly Main main;
public Sub(Main main)
{
InitializeComponent();
this.main = main;
systinfo = mainfrm.stateInfo;
}
那么,警告告诉了你什么<代码>表单继承自MarshalByRefObject
。这意味着您可能实际上没有传递真正的表单
对象-例如,您完全可能只有远程计算机上的表单
的代理。这意味着对类型的所有调用都会通过代理自动封送,在实际实例上执行,并返回结果。由于state
是一个struct
(我打赌这是因为您不理解C#的struct
和C的struct
之间的区别),它是一种值类型-如果您确实持有代理而不是真实实例,这将导致运行时异常
为了避开警告,您可以先将状态
复制到本地,这样可以确保安全(更重要的是,显而易见)
当你从C++到C语言时,你会掉进很多陷阱,它们看起来很相似,但是有很多不同之处。在你实际操作之前,试着查一下你试图使用的任何东西。例如,查找<代码> REF 关键字会使你明显地指向指针,并且查找<代码> Stutt和用C#编写习惯用法变得更加严重。例如,您通常在需要的地方创建子窗体和对话框,而不是在构造函数中创建实例并在需要时重用它。当然,循环引用通常是一个糟糕的想法——它是增加代码复杂度的一个好方法,并且它使调试和测试更加昂贵。进一步的重构对循环引用的伤害更大。请提供一个完整有效的示例
public void state systinfo
显然是无效的,您的示例中还有其他方面很难理解。如果您可以遵循.NET命名约定,那么它也会更清晰。从public Sub(ref Main)
中去掉ref
。在C++语句中,您的代码通过一个指针传递给代码< main >代码>,这不是您想在这里做的。@当我实现“CPNe=新的子(REF main)”时,自动地构造了DavidArno:<代码>公子子(REF main main)< /C> >;此外,当我试图修改它时,它会抛出一个错误。谢谢你的回复。但问题依然存在systinfo.X
仍然生成空值,mainfrm.stateInfo
虽然生成输出,但抛出CS1690异常(通过引用封送)。@srivas为什么不应该是null
?你从来没有初始化过它。我是这样初始化它的:public Sub(Main Main){InitializeComponent();this.Main=Main;systino=new state();systino=mainfrm.stateInfo;}
@srivas你可能没有意识到这一点,但你只是创建了一个新实例(fine),将它分配给一个字段(fine),然后立即将其替换为来自mainfrm
的统一化对象。请推荐初始化对象(systinfo
)的正确方法,该方法涵盖了由于直接调用(mainfrm.stateinfo
)而导致的引用覆盖marshall的方面。对不起,我犯了一个很大的错误。此处,mainfrm
和main
处于启用状态,并且相同。