C# 全局对象实例?
我想创建一个全局实例,但不知道是否可能,以下面的示例为例C# 全局对象实例?,c#,class,object,instance,global,C#,Class,Object,Instance,Global,我想创建一个全局实例,但不知道是否可能,以下面的示例为例 class ProgramGlobals { public String_Example Test {get; set; } } class Program { static void SetupFactory() { var builder = new ContainerBuilder(); builder.RegisterType<ProgramGlobals>()
class ProgramGlobals
{
public String_Example Test {get; set; }
}
class Program
{
static void SetupFactory()
{
var builder = new ContainerBuilder();
builder.RegisterType<ProgramGlobals>().SingleInstance();
}
static void Main()
{
SetUpFactory();
var globals = Container.Resolve<ProgramGlobals>();
globals.Test = null;
Form1 frm = new Form1();
Application.Run(frm);
MessageBox.Show(globals.Test._str);
}
}
public partial class Form1: Form
{
private voide button1_Click(object sender, EventArgs e)
{
var globals = Container.Resolve<ProgramGlobals>();
globals.Test._str = new String_Example(textbox1.Text)
}
}
我有一个字符串示例类:
namespace Pass_Object_as_Reference_Example
{
public class String_Example
{
public string _str {get;set;}
public String_Example(string Cadena)
{
_str = Cadena;
}
}
}
这是我的Form1代码:
public partial class Form1 : Form
{
String_Example cadena;
public Form1(ref String_Example str)
{
InitializeComponent();
cadena = str;
}
private void button1_Click(object sender, EventArgs e)
{
cadena = new String_Example(textBox1.Text);
this.Close();
}
}
这是我的主要代码:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
String_Example test = null;
Form1 frm = new Form1(ref test);
Application.Run(frm);
MessageBox.Show(test._str);
}
这就是我所想象的:
null
对吗
我应该在主代码中创建对象,然后在后续表单中修改参数吗?您的代码正在做什么
test
设置为空引用
test
的引用的引用。如果您只想传递引用,请删除ref
关键字。作为引用类型的变量的值已经只是对对象的引用。ref对象不是对对象的引用,而是对对象引用的引用。请查看这是否为否你不清楚
cadena
3a.(因为它们是对象,通过引用传递,我猜Cadena现在有了测试地址)
否。它的值为test
,这是一个空引用。我认为您试图存储对对象引用的引用(即指向test
)的指针。实际上,您只存储了一个与test
中保存的值相等的指针,在本例中,该值为空
test
的代码
为什么这永远行不通
如果要传递指向变量的指针,则需要使用非托管代码,如下所示:
在不安全上下文中类型可以是指针类型、值类型或引用类型。指针类型声明采用以下形式之一:
(增加重点)
<>你不能在C++中做……而且在C++中,我也不会这么做,因为不能保证指针会被垃圾收集。这就是为什么在托管代码中不允许使用这种模式的原因。
如何做你想做的事
我给你三个选择。可能还有一些(Singleton、ByRef等),但我认为这些是最常见的
在程序和表单之间设置父/子项
如果您正在编写一个应用程序,其中有一系列表单需要访问全局状态,那么一个常见的模式是将程序本身作为全局状态的容器,并将其作为父级
参数传递给任何需要它的对象。下面是您的代码,遵循此模式:
public class String_Example
{
public string _str {get;set;}
public String_Example(string Cadena)
{
_str = Cadena;
}
}
public partial class Form1 : Form
{
readonly Program _parent; //Reference to class which contains global state. readonly = can only be set in constructor and can never change.
public Form1(Program parent)
{
InitializeComponent();
_parent = parent;
}
private void button1_Click(object sender, EventArgs e)
{
_parent.test = new String_Example(textBox1.Text);
this.Close();
}
}
public class Program
{
public String_Example test; //Notice this is now a member variable
static public void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
test = null;
Form1 frm = new Form1(this);
Application.Run(frm);
MessageBox.Show(test._str);
}
}
使全局变量保持静态
或者,如果不想将指针传递给子对象,可以将全局变量设置为静态变量:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Program.test = new String_Example(textBox1.Text);
this.Close();
}
}
public class Program
{
static public String_Example test; //Notice this is now a static variable, so it can be accessed without a reference to an instance of Program
static public void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
test = null;
Form1 frm = new Form1(this);
Application.Run(frm);
MessageBox.Show(test._str);
}
}
最佳方式
最好的方式,或者说是当今最时髦的方式,就是
创建专门用于包含全局状态的类
将状态变量实现为成员变量
使用类似Autofac的工厂获取状态容器的实例
告诉工厂你只想要一个实例,不管你调用它多少次
比如说
class ProgramGlobals
{
public String_Example Test {get; set; }
}
class Program
{
static void SetupFactory()
{
var builder = new ContainerBuilder();
builder.RegisterType<ProgramGlobals>().SingleInstance();
}
static void Main()
{
SetUpFactory();
var globals = Container.Resolve<ProgramGlobals>();
globals.Test = null;
Form1 frm = new Form1();
Application.Run(frm);
MessageBox.Show(globals.Test._str);
}
}
public partial class Form1: Form
{
private voide button1_Click(object sender, EventArgs e)
{
var globals = Container.Resolve<ProgramGlobals>();
globals.Test._str = new String_Example(textbox1.Text)
}
}
类程序全局
{
公共字符串_示例测试{get;set;}
}
班级计划
{
静态无效设置工厂()
{
var builder=new ContainerBuilder();
builder.RegisterType().SingleInstance();
}
静态void Main()
{
SetUpFactory();
var globals=Container.Resolve();
globals.Test=null;
Form1 frm=新Form1();
应用程序运行(frm);
MessageBox.Show(globals.Test.\u str);
}
}
公共部分类Form1:Form
{
私有作废按钮1\u单击(对象发送者,事件参数)
{
var globals=Container.Resolve();
globals.Test.\u str=新字符串\u示例(textbox1.Text)
}
}
您可以自由使用任何您想要的工具包,例如或。这将比较.NET可用的主要IoC库
这种方法是首选的,因为它允许单元测试人员为全局状态提供他们自己的存根,而不需要全局状态,这通常是设置单元测试的最困难部分
请注意,在上面的示例中,我通过执行代码获取对ProgramGlobals的引用。您也可以使用.Great topic设置对象以自动获取引用,但我的答案已经很长了,因此您可能需要自己进行研究。您的代码在做什么
创建“测试”对象空
实际上,您没有创建对象。您正在将test
设置为空引用
将对象作为引用传递给窗体
实际上,您正在将引用传递给测试的引用。如果您只想传递引用,请删除
var byRef = new ByRef<String_Example>();
Form1 frm = new Form1(byRef);
public partial class Form1 : Form
{
ByRef<String_Example> cadena;
public Form1(ByRef<String_Example> str)
{
if (str == null)
throw new ArgumentNullException("str");
InitializeComponent();
cadena = str;
}
private void button1_Click(object sender, EventArgs e)
{
cadena.Value = new String_Example(textBox1.Text);
this.Close();
}
}