0

I want to make a simple TCP server in C# so I want to define some variables but I can't access the variables which I declared. Is it possible to bypass this?

Current code:

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 System.Net;
using System.Net.Sockets;

namespace TCP_Server_gui
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        string serverIp = "127.0.0.1";
        int serverPort = 4200;

        IPAddress localAdd = IPAddress.Parse(serverIp);
        TcpListener listener = new TcpListener(localAdd, serverPort);
    }
}

I get those errors:

Severity  Code  Description
Error   CS0236  A field initializer cannot reference the non-static field, method, or property 'Form1.serverIp'
Error   CS0236  A field initializer cannot reference the non-static field, method, or property 'Form1.localAdd'
Error   CS0236  A field initializer cannot reference the non-static field, method, or property 'Form1.serverPort'
MethodMan
  • 18,625
  • 6
  • 34
  • 52
Gewoo
  • 109
  • 1
  • 3
  • 10
  • You are declaring those variables as private member variables, then wherever you are using them you're trying to refer to them as static variables of the class. If you look up that error, you'll find examples of what you're doing wrong. – tbddeveloper Feb 04 '16 at 17:16
  • here is a good link to read and understand in regards to [Encapsulation](http://www.csharp-station.com/Tutorial/CSharp/Lesson19) – MethodMan Feb 04 '16 at 17:18
  • @MethodMan Thanks for the link I will definitely read it. – Gewoo Feb 04 '16 at 17:23

3 Answers3

3

Put the non-constant initializers in the constructor instead:

    public Form1()
    {
        InitializeComponent();

        localAdd = IPAddress.Parse(serverIp);
        listener = new TcpListener(localAdd, serverPort);
    }

    string serverIp = "127.0.0.1";
    int serverPort = 4200;

    IPAddress localAdd;
    TcpListener listener;
}

The reason is because there's no guarantee that field initializers run in any specific order, so there's no guarantee that serverIp will be initialized when the initializer for IPAddress runs. If you put them in the constructor you control the order.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
3

C# is a strictly object-oriented language (for a certain definition of OOP :P), so there are no C-style variables. Instead, you have fields and locals.

In your case, you've declared multiple fields. However, fields (unlike C-style variables and C#'s locals) have no defined order of execution, so their initializers can't reference each other. Instead, you need to move the initializers to the constructor:

public Form1()
{
    InitializeComponent();

    localAdd = IPAddress.Parse(serverIp);
    listener = new TcpListener(localAdd, serverPort)
}

string serverIp = "127.0.0.1";
int serverPort = 4;

IPAddress localAdd;
TcpListener listener;
Luaan
  • 62,244
  • 7
  • 97
  • 116
1

You have to call your methods inside form constructor:

public partial class Form1 : Form
{
    string serverIp = "127.0.0.1";
    int serverPort = 4200;

    public Form1()
    {
            InitializeComponent();
            IPAddress localAdd = IPAddress.Parse(serverIp);
            TcpListener listener = new TcpListener(localAdd, serverPort);
     }
}

if you want localAdd and listener to be accessed globally in your class then you will have to move them outside constructor:

public partial class Form1 : Form
{
    string serverIp = "127.0.0.1";
    int serverPort = 4200;

    IPAddress localAdd;
    TcpListener listener;
    public Form1()
    {
            InitializeComponent();
            localAdd = IPAddress.Parse(serverIp);
            listener = new TcpListener(localAdd, serverPort);
     }
}
Ehsan Sajjad
  • 61,834
  • 16
  • 105
  • 160