c#编码惯例公共/私人情境

时间:2012-12-14 14:26:43

标签: c# winforms conventions

我正在学习C#,我正在创建一个简单的WinForms应用程序,它的作用是启动一个简单的OpenVPN客户端:

    void button_Connect_Click(object sender, EventArgs e)
    {
        var proc = new Process();
        proc.StartInfo.FileName = "CMD.exe";
        proc.StartInfo.UseShellExecute = false;
        proc.StartInfo.WorkingDirectory = @"C:\Program Files (x86)\OpenVPN\bin";
        proc.StartInfo.Arguments = "/c openvpn.exe --config config.ovpn --auto-proxy";

        // set up output redirection
        proc.StartInfo.RedirectStandardOutput = true;
        proc.StartInfo.RedirectStandardError = true;
        // Input
        proc.StartInfo.RedirectStandardInput = true;

        // Other
        proc.EnableRaisingEvents = true;
        proc.StartInfo.CreateNoWindow = false;
        // see below for output handler
        proc.ErrorDataReceived += proc_DataReceived;
        proc.OutputDataReceived += proc_DataReceived;

        proc.Start();

        StreamWriter myStreamWriter = proc.StandardInput;
        proc.BeginErrorReadLine();
        proc.BeginOutputReadLine();

        proc.WaitForExit();
    }

    void proc_DataReceived(object sender, DataReceivedEventArgs e)
    {
        // output will be in string e.Data
        if (e.Data != null)
        {
            string Data = e.Data.ToString();
            if (Data.Contains("Enter Auth Username"))
            {
                myStreamWriter("myusername");
            }
            //MessageBox.Show(Data);
        }
    }

它现在做的是将CMD的所有输出发送到我的程序,该程序根据输出运行命令。

我目前的问题是,我需要写入流。我在myStreamWriter中使用proc_DataReceived,但它不在同一个上下文中,因此无效。

我收到以下错误:The name 'myStreamWriter' does not exist in the current context,在该范围内显然不存在。

如何使这项工作?获取/设置属性?就像我说的那样,我对C#很陌生,所以对任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:2)

在表单中,添加以下字段:

public class Form1Whatevver: Form {
    private StreamWriter myStreamWriter;
}

然后在你的代码中:

proc.Start();

this.myStreamWriter = proc.StandardInput;

proc.BeginErrorReadLine();
proc.BeginOutputReadLine();

现在,myStreamWriter将可用于proc_DataReceived()

void proc_DataReceived(object sender, DataReceivedEventArgs e)
    {
        // output will be in string e.Data
        if (e.Data != null)
        {
            string Data = e.Data.ToString();
            if (Data.Contains("Enter Auth Username"))
            {
                if (myStreamWriter != null) // Just in case
                {
                    myStreamWriter("myusername");
                }
            }
            //MessageBox.Show(Data);
        }
    }

答案 1 :(得分:1)

您所谈论的概念是Scope而非背景。


您可以通过多种方式更改代码,以便从myStreamWriter访问proc_DataReceived

可以说是最简单的,就是将你想要效果的对象作为参数传递给函数。从未来的多线程和实现功能的角度来看,这通常是一种很好的方法。

    void proc_DataReceived(
        object sender, 
        DataReceivedEventArgs e,
        StreamWriter writer)
    {
        ...
        writer("myusername");
        ...
    }

然而,proc_DataReceived显然是一个事件处理程序,您可能不想更改该函数的签名。


如果您在班级级别将myStreamWriter声明为私有成员变量,则可以从班级中的任何位置进行访问。 this是可选的但很好的形式。

class YourForm : Form
{
    private StreamWriter myStreamWriter;

    void button_Connect_Click(...
    {
        ...
        this.myStreamWriter = proc.StandardInput;
        ...
    }

    void proc_DataRecieved(...
    {
        ...
        this.myStreamWriter("myusername");
        ...

    }
}

除非您想从类/表单外部访问StreamWriter,否则不需要执行属性。

答案 2 :(得分:1)

简单的快速修复是将myStreamWriter定义为类中的一个字段(即在方法的范围之外),然后在其中一个范围内实例化它:

private StreamWriter _myStreamWriter;

void button_Connect_Click(object sender, EventArgs e)
{
    // Do some stuff

    _myStreamWriter = proc.StandardInput;

    // Do some stuff
}

这样做可以让你在课堂上的任何地方使用它。