0

I'm trying to implement the An even better solution version of the top answer to this question, offered by Fredrik Mork. Since I am new to stack overflow, I don't have enough reputation points to add a comment to his answer, asking him directly. How do I get his attention to this question? @FredrikMork ? @fredrik-mork ?

In Fredrik's solution, he provides 3 pieces of example code. First is the interface declaration, second shows the class with the property that needs to be manipulated from the other class, then 3rd is the other class, but I don't know what the code in the other class does

Please note that I am new to C# and OOP ( I am working my way through //Step by step Microsoft Visual C# 2013 by John Sharp) @JohnSharp

I'm doing a Windows Forms solution in .NET 2.0(Using API to control a Bluetooth dongle that was made in .NET 2.0), in VS 2013.

I made the interface based on the answer to the question mentioned above, except in my case I'm trying to add a string generated in CCINS_Comm class to a listbox in the form of my Form1 class.

So, in Program.cs I have:

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
                        }

                    }
                }
            };
        }
   }
}

Then, in Form1.cs I have

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);
        }

    }
}

Before you mark this as a duplicate question and ruin any chances of me getting help, please note that I have searched on the error code and have found no answers that relate to problems with interfaces.

When I run this with debugging turned on, I get An unhandled exception of type 'System.NullReferenceException' occurred in EP1 Additional information: Object reference not set to an instance of an object.

I don't understand why I get Object reference not set to an instance of an object. I'm already checking to make sure the string I intend to pass is not empty.

EDIT1: this is not a duplicate question to this question, as none of that answers relate to interfaces. This question is about how to correctly construct an interface.

EDIT2: I'm updating the code with my latest attempt to solve the problem. Still doesn't work, but I think I'm closer.

EDIT3: Edited code to reflect the solution provided that gets me past the original error but now another error happens. Also moved these edit notes down to the bottom of the question text box.

Community
  • 1
  • 1
Greg
  • 15
  • 7
  • 1
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](http://stackoverflow.com/questions/4660142/). Also, if you want to get Fredrik's attention the you should go to his profile and contact him through twitter/linkedin/etc. – Nasreddine May 30 '16 at 19:51
  • @Nasreddine I have looked at all of the answers to that question and none of them apply to interfaces. Please reference the answer that fits my question – Greg May 30 '16 at 20:00
  • Folks, I'm trying to learn how to do an interface here. – Greg May 30 '16 at 20:05
  • The problem is that you are trying to use something that is `null` and you're getting an exception. Just because you are trying to do something with interfaces doesn't mean that any problem you encounter must be related to interfaces. – BJ Myers May 30 '16 at 20:30
  • @BJMyers, I understand the error code is indicating that, but the error code comes from the interface I'm trying to implement and I don't know why. As mentioned, the string I'm trying to pass is checked to not be null. – Greg May 30 '16 at 21:10
  • Folks, for just a moment, please ignore the error code that I'm getting and just help me learn how to properly do an interface. That is what this question is about. How do I do an interface? Look at my code, there's this part which I don't understand what it does. – Greg May 30 '16 at 21:13
  • 1
    Your interface is fine. We can't ignore the error code because that is the ENTIRE problem here. Your car's engine is smoking but you keep asking us to please ignore that so that we can make sure your mirrors are adjusted correctly. – BJ Myers May 30 '16 at 23:56
  • @BJMyers, that's a nice snarky remark. I'm just trying to get help with my code here. Your remarks aren't helping me, your re-iteration of the error code wasn't really helpful either, although I'm guessing you gain some satisfaction from being right? – Greg May 31 '16 at 03:44
  • Folks, I'm trying to implement the interface solution provided as an answer to a previous problem. I *think* the issues is about my adaptation of the code from that answer. My most recent hint is that my interface is fine. That would seem to mesh with the one helpful answer I got below. Unfortunately, even that most helpful response is over my head. – Greg May 31 '16 at 04:01
  • Can anyone explain the answer below? How does one initialize ccinsComm inside the Form1 constructor and pass it an object that implements IForm1Interface as a parameter? Also, why didn't this need to be done in the example that I adapted my code from? – Greg May 31 '16 at 04:09
  • I just changed the code in the question. Previously there was a default constructor and then a constructor for the interface that had a parameter. I combined these to make one single constructor. Then in the Form1 class, I create an object of the IForm1Interface type and use that as a argument for when I call the CCINS_Comm constructor. Now I get an error on iFaceObj, A field initializer cannot reference the non-static field, method, or property 'EP1.Form1.iFaceObj' So I know that when I call that constructor, I need an argument, but what to use? Any help would be appreciated. – Greg May 31 '16 at 04:46

1 Answers1

1

Your error comes from this line:

CCINS_Comm ccinsComm = new CCINS_Comm(); 

You are creating a new instance of CCINS_Comm but the default parameterless constructor doesn't set a value for CCINS_Comm.form1 which defaults to null (hence the NullReferenceException). To fix this you need to initialize ccinsComm inside the Form1 constructor and pass it an object that implements IForm1Interface as a parameter.

Nasreddine
  • 36,610
  • 17
  • 75
  • 94
  • Thanks for helping, and keeping in mind I am a C#/OOP beginner. OK, I think I understand the reason you are providing. Based on your explanation, I need to add a statement to the Form1 constructor that initializes ccinsComm and passes ccinsComm an object that implements IForm1Interface as a parameter. So, that statement must start with `ccinsComm.form1 =` but I don't know what to set it equal too. Can you explain "object that implements IForm1Interface as a parameter"? How do you implement an interface as a parameter? – Greg May 30 '16 at 22:19
  • Also, could you take a look at my code at the line with the comment `// What does this statement do?` and the following 4 lines. This I tried to adapt from Fredrik's example, but I don't know what it does or why/if I need it. Thanks! – Greg May 30 '16 at 22:28
  • Thinking about this more...The CCINS_Comm() class has its default constructor, and then, I *think* the additional constructor that I adapted from Fredrik's example. Seem like it would be great if I could somehow combine the two somehow. Then when the default constructor is called, the CCINS_Comm.form1 thing gets initialized. – Greg May 30 '16 at 23:49
  • I just changed the code in the question. Previously there was a default constructor and then a constructor for the interface that had a parameter. I combined these to make one single constructor. Then in the Form1 class, I create an object of the IForm1Interface type and use that as a argument for when I call the CCINS_Comm constructor. Now I get an error on iFaceObj, A field initializer cannot reference the non-static field, method, or property 'EP1.Form1.iFaceObj' So I know that when I call that constructor, I need an argument, but what to use? Any help would be appreciated. – Greg May 31 '16 at 04:47
  • 2
    Read the last sentence from the answer: *To fix this you need to initialize `ccinsComm` inside the `Form1` constructor and pass it an object that implements IForm1Interface as a parameter.*. In other words, remove `IForm1Interface iFaceObj;` line, change the next line to `CCINS_Comm ccinsComm;` and insert the following line in the form constructor right after `InitializeComponent` line: `ccinsComm = new CCINS_Comm(this);` and you are done. – Ivan Stoev May 31 '16 at 06:41
  • @Greg Do exactly what Ivan Stoev said and your problem will be solved. – Nasreddine May 31 '16 at 07:37
  • Thanks, guys. That seems to have done the trick. I'm now on to a different error, which I won't go into here. Meanwhile, the keyword this is explained [here](https://msdn.microsoft.com/en-us/library/dk1507sz%28v=vs.120%29.aspx). See the part where it says To pass an object as a parameter to other methods... – Greg May 31 '16 at 18:21