繁体   English   中英

无法使用第三方提供的类通过嵌套类型访问外部类型XXX的非静态成员

[英]Cannot access a non-static member of outer type XXX via nested type with a third-party provided class

总的来说,这个问题已在SOF中得到解决。 但是,我无法(不够胜任)将建议应用于此示例。 我收到“无法通过嵌套类型访问外部类型为'FixClientTest.Form1'的非静态成员...”错误。 在这种情况下,嵌套类型是第三方提供的类的实例化(在这种情况下,为开源QuickFix / n库)。 我知道来源并不真正相关,但是我试图避免提出任何建议,这些建议可能会让我修改该代码并且不具备解决该问题的知识。 我的目标只是根据我从该库的回调中获取的信息来更新表单控件。 (下面的代码只是一个简单的表单,带有2个按钮,一个按钮用于设置事件回调,另一个按钮用于停止事件回调。)我将非常感谢社区可能提出的任何建议。

谢谢。

using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using QuickFix;

namespace FixClientTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public class MyQuickFixApp : QuickFix.IApplication
        {    
            public void FromApp(QuickFix.Message msg, SessionID sessionID) { }
            public void OnCreate(SessionID sessionID) { }
            public void OnLogout(SessionID sessionID) 
            {
                Console.WriteLine("Logged out.");
            }
            public void OnLogon(SessionID sessionID) 
            {
                Console.WriteLine("Logged In.");
            }
            public void FromAdmin(QuickFix.Message msg, SessionID sessionID) 
            {
                //logListView.Items.Add(msg.ToString()); <<GENERATES ERROR!

            }
            public void ToAdmin(QuickFix.Message msg, SessionID sessionID) { }
            public void ToApp(QuickFix.Message msg, SessionID sessionID) { }
        }

        public QuickFix.Transport.SocketInitiator _Initiator = null;

        private void connectButton_Click(object sender, EventArgs e)
        {
            string file = "c:/FIX/tradeclientIB.cfg";
            try
            {
                QuickFix.SessionSettings settings = new QuickFix.SessionSettings(file);
                QuickFix.IApplication myApp = new MyQuickFixApp();
                QuickFix.IMessageStoreFactory storeFactory = new QuickFix.FileStoreFactory(settings);
                QuickFix.ILogFactory logFactory = new QuickFix.ScreenLogFactory(settings);
                _Initiator = new QuickFix.Transport.SocketInitiator(myApp, storeFactory, settings, logFactory);   
                _Initiator.Start();

            }
            catch (System.Exception err)
            {
                MessageBox.Show(err.ToString());
            }
        }

        private void stopButton_Click(object sender, EventArgs e)
        {
            _Initiator.Stop();
        }
    }
}

您的MyQuickFixApp类对Form1对象一无所知。

首先,我建议将其移出Form1类。 然后,我将研究如何以及何时创建MyQuickFixApp对象。 我对QuickFix库不熟悉,但是快速浏览一下文档表明在按钮消息处理程序中创建它不是正确的方法。 (在Winforms应用程序中,我想您会在Program.Main方法中创建它)。

至于实际的错误,您需要给MyQuickFixApp对象一个对Form1对象的引用(可能在构造函数中传递它)。

public class MyQuickFixApp : QuickFix.IApplication
{
    private readonly Form1 _form1;
    public MyQuickFixApp(Form1 form)
    {
       _form1 = form;
    }

    public void FromAdmin(QuickFix.Message msg, SessionID sessionID) 
    {
        _form1.logListView.Items.Add(msg.ToString());
    }
}

在等待答案的过程中,我再次查看了此链接中提供的答案: 财产由于其保护等级而无法访问当我再次仔细阅读它时,我意识到史蒂夫已经发布了我需要的答案,因此真的是他的答案。 我需要使用事件来重组它,以捕获表单中的更改并保留封装。 这也使我可以将更新了表单的类移出Form类,但是,这却引起了人们普遍担心的“跨线程”问题。 我已经从其他人那里得到了答案(对不起,没有该链接)。 我向事件添加了行,以更新表单以将其拆分为新线程。 我以前做过,而且效果很好。 如果有人认为这可能是个问题,请告诉我。 抱歉,如果我浪费任何时间在看我的问题上,但是我想我会分享一些答案,因为它解决了自学习c#/ forms以来我遇到的两个最大问题。

一件事,不要对这个声明感到困惑: private delegate void AddLogItemDelegate(string msg); 它与创建包含AddLogItem函数的线程有关,与事件的创建无关。

谢谢

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using QuickFix;

namespace FixClientTest
{

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public QuickFix.Transport.SocketInitiator _Initiator = null;

        private void connectButton_Click(object sender, EventArgs e)
        {
            string file = "c:/FIX/tradeclientIB.cfg";
            try
            {
                QuickFix.SessionSettings settings = new QuickFix.SessionSettings(file);
                QuickFix.IApplication myApp = new MyQuickFixApp();
                QuickFix.IMessageStoreFactory storeFactory = new QuickFix.FileStoreFactory(settings);
                QuickFix.ILogFactory logFactory = new QuickFix.ScreenLogFactory(settings);
                //QuickFix.Transport.SocketInitiator initiator = new QuickFix.Transport.SocketInitiator(myApp, storeFactory, settings, logFactory);
                _Initiator = new QuickFix.Transport.SocketInitiator(myApp, storeFactory, settings, logFactory);

                MyQuickFixApp.UpdateEvent += new MyQuickFixApp.OnUpdateEvent(AddLogItem);
                _Initiator.Start();

            }
            catch (System.Exception err)
            {
                Console.WriteLine(err.Message);
                Console.WriteLine(err.StackTrace);
                MessageBox.Show(err.ToString());
            }
        }

        private void stopButton_Click(object sender, EventArgs e)
        {
            _Initiator.Stop();
        }
        public string stuff;

        private delegate void AddLogItemDelegate(string msg);
        public void AddLogItem(string msg)
        {
            if(this.InvokeRequired)
            {
                this.Invoke(new AddLogItemDelegate(AddLogItem), new object[] { msg });
                return;
            }

            try
            {
                logListView.Items.Add(msg);
            }
            catch(Exception err)
            {
                MessageBox.Show(err.ToString());
            }
        }
    }


    public class MyQuickFixApp : QuickFix.IApplication
    {

        public delegate void OnUpdateEvent(string msg);
        public static event OnUpdateEvent UpdateEvent;

        public void FromApp(QuickFix.Message msg, SessionID sessionID) { }
        public void OnCreate(SessionID sessionID) { }
        public void OnLogout(SessionID sessionID)
        {
            Console.WriteLine("Logged out.");
        }
        public void OnLogon(SessionID sessionID)
        {
            UpdateEvent("STUFF!!");
            Console.WriteLine("Logged In.");
        }
        public void FromAdmin(QuickFix.Message msg, SessionID sessionID)
        {

        }
        public void ToAdmin(QuickFix.Message msg, SessionID sessionID) { }
        public void ToApp(QuickFix.Message msg, SessionID sessionID) { }
    }


}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM