【问题标题】:C# winforms .NET2.0 Class Interface IssueC# winforms .NET2.0 类接口问题
【发布时间】:2016-09-28 16:51:24
【问题描述】:

我正在尝试实现由 Fredrik Mork 提供的this question 的最佳答案的更好的解决方案 版本。由于我是堆栈溢出的新手,我没有足够的声誉点来为他的答案添加评论,直接问他。我如何让他注意到这个问题? @弗雷德里克莫克? @弗雷德里克-莫克?

在 Fredrik 的解决方案中,他提供了 3 段示例代码。第一个是接口声明,第二个显示需要从其他类操作的属性的类,然后第3个是其他类,但我不知道其他类中的代码是做什么的

请注意,我是 C# 和 OOP 的新手(我正在努力通过 //Step by step Microsoft Visual C# 2013 by John Sharp)@JohnSharp

我正在 VS 2013 中使用 .NET 2.0(使用 API 控制在 .NET 2.0 中制作的蓝牙加密狗)中的 Windows 窗体解决方案。

我根据上面提到的问题的答案制作了界面,除了在我的情况下,我试图以我的 Form1 类的形式将 CCINS_Comm 类中生成的字符串添加到列表框中。

所以,在 Program.cs 我有:

namespace EP1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    class CCINS_Comm : IDisposable
    {
        // Other stuff like constants
        //                  members
        //                  properties




        // combined constructors  this was fine...
        public CCINS_Comm(IForm1Interface form1)
        {
            m_communicator = null;
            m_deviceCb = null;
            m_bleMgrCb = null;
            m_peerDevice = null;
            m_gattClientCb = null;
            this.form1 = form1;
        }


        /// <summary>
        /// Start scan
        /// </summary>
        public CyApiErr StartScan()
        {
            return StartScanHelper();
        }

     /// <summary>
    /// Setup the scan result handler to log the discovered BLE devices
    /// </summary>
    private void SetupScanResultHandler()
        {
            m_scanCb.ScanResultHandler = (result) =>
            {
                if (result != null)
                {
                    StringBuilder SB = new StringBuilder();
                    foreach (var item in result.ScanRecords)
                    { 
                        SB.Length = 0;
                        SB.AppendFormat("Peer device: [{0:X12}, {1}], ADV_TYPE: {2}, RSSI: {3}",
                            item.PeerDeviceAddress.Address,
                            item.PeerDeviceAddress.AddressType,
                            item.AdvertisementType,
                            item.RSSI);
                        if(SB.ToString() != "")
                        {
                            string str = SB.ToString();    // Troubleshooting
                            form1.AddToScanResultsList(str); // Object reference not set to an instance of an object Error happens here
                        }

                    }
                }
            };
        }
   }
}

然后,在 Form1.cs 我有

namespace EP1
{

    // This is the interface.  this is in the right place (not in either class)
    interface IForm1Interface
    {
        void AddToScanResultsList(string resultString);
    }



    public partial class Form1 : Form, IForm1Interface
    {

        CCINS_Comm ccinsComm; 


        public Form1()
        {
            InitializeComponent();
            InitalizeStimControls();
            ccinsComm = new CCINS_Comm(this);
        }


       // various methods handling manipulation of controls, etc.


        // method that the interface refers to 
        public void AddToScanResultsList(string resultString)
        {
            listBoxScanResults.Items.Add(resultString);
        }

    }
}

在您将此标记为重复问题并破坏我获得帮助的任何机会之前,请注意,我已经搜索了错误代码,但没有找到与接口问题相关的答案。

当我在打开调试的情况下运行此程序时,我得到了 EP1 中发生了“System.NullReferenceException”类型的未处理异常附加信息:对象引用未设置为对象的实例。

我不明白为什么我没有将对象引用设置为对象的实例。我已经在检查以确保我打算传递的字符串不为空。

EDIT1:这不是this question 的重复问题,因为这些答案都与接口无关。本题是关于如何正确构建接口的问题。

EDIT2:我正在用我最近尝试解决问题的方法更新代码。仍然不起作用,但我想我更接近了。

EDIT3:编辑代码以反映提供的解决方案,使我摆脱了原始错误,但现在发生了另一个错误。还将这些编辑注释移至问题文本框的底部。

【问题讨论】:

  • What is a NullReferenceException, and how do I fix it? 的可能重复项。此外,如果您想引起 Fredrik 的注意,您应该转到他的个人资料并通过 twitter/linkedin/etc 与他联系。
  • @Nasreddine 我已经查看了该问题的所有答案,但没有一个适用于接口。请参考适合我的问题的答案
  • 伙计们,我正在尝试在这里学习如何做一个界面。
  • 问题是您尝试使用 null 的东西,但您遇到了异常。仅仅因为你试图用接口做一些事情并不意味着你遇到的任何问题都必须与接口有关。
  • 你的界面很好。我们不能忽略错误代码,因为这是这里的整个问题。您的汽车引擎在冒烟,但您一直要求我们不要理会它,以便我们确保您的后视镜调整正确。

标签: c# winforms interface


【解决方案1】:

您的错误来自这一行:

CCINS_Comm ccinsComm = new CCINS_Comm(); 

您正在创建CCINS_Comm 的新实例,但默认的无参数构造函数没有为CCINS_Comm.form1 设置默认值null(因此是NullReferenceException)。要解决此问题,您需要在 Form1 构造函数中初始化 ccinsComm,并将实现 IForm1Interface 的对象作为参数传递给它。

【讨论】:

  • 感谢您的帮助,请记住我是 C#/OOP 初学者。好的,我想我明白你提供的原因。根据您的解释,我需要在 Form1 构造函数中添加一条语句,用于初始化 ccinsComm 并将实现 IForm1Interface 的对象作为参数传递给 ccinsComm 。因此,该语句必须以ccinsComm.form1 = 开头,但我也不知道如何将其设置为相等。你能解释一下“实现 IForm1Interface 作为参数的对象”吗?如何将接口实现为参数?
  • 另外,你能看看我的代码在注释 // What does this statement do? 的行和下面的 4 行。我试图从 Fredrik 的示例中进行调整,但我不知道它的作用或为什么/是否需要它。谢谢!
  • 再想一想...CCINS_Comm() 类有它的默认构造函数,然后,我认为我改编自 Fredrik 的示例的附加构造函数。如果我能以某种方式将两者结合起来,似乎会很棒。然后当调用默认构造函数时,CCINS_Comm.form1 事物被初始化。
  • 我刚刚更改了问题中的代码。以前有一个默认构造函数,然后是具有参数的接口的构造函数。我将这些组合成一个构造函数。然后在 Form1 类中,创建一个 IForm1Interface 类型的对象,并将其用作调用 CCINS_Comm 构造函数时的参数。现在我在 iFaceObj 上收到一个错误,字段初始化程序无法引用非静态字段、方法或属性 'EP1.Form1.iFaceObj' 所以我知道当我调用该构造函数时,我需要一个参数,但要使用什么?任何帮助将不胜感激。
  • 阅读答案的最后一句话:要解决此问题,您需要在 Form1 构造函数中初始化 ccinsComm,并将实现 IForm1Interface 的对象作为参数传递给它。。换句话说,删除IForm1Interface iFaceObj;行,将下一行更改为CCINS_Comm ccinsComm;,并在InitializeComponent行之后插入以下行:ccinsComm = new CCINS_Comm(this);,您就完成了。
猜你喜欢
  • 2012-11-16
  • 2010-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多