I am not sure why when I don't use "static", the function has error:
"An object reference is required for non-static field,method, or property.Dos2Unix(string)"
The code looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var f = #"\D:\temp\test.xls";
Dos2Unix(f);
}
private void Dos2Unix(string fileName)
{
const byte CR = 0x0D;
const byte LF = 0x0A;
byte[] data = File.ReadAllBytes(fileName);
using (FileStream fileStream = File.OpenWrite(fileName))
{
BinaryWriter bw = new BinaryWriter(fileStream);
int position = 0;
int index = 0;
do
{
index = Array.IndexOf<byte>(data, CR, position);
if ((index >= 0) && (data[index + 1] == LF))
{
// Write before the CR
bw.Write(data, position, index - position);
// from LF
position = index + 1;
}
}
while (index > 0);
bw.Write(data, position, data.Length - position);
fileStream.SetLength(fileStream.Position);
}
}
}
}
When I use the keyword "static", there is no error.
I am not sure what error I am making. Need some help on this.
When calling non-static method this parameter implictly passed into the method
private void Dos2Unix(string fileName) {
...
var sample = this.GetType(); // <- possible call
...
}
Static method can't provide such parameter (this) and so you have an error.
In your case you don't want Program class instance within Dos2Unix method, so make it static:
class Program
{
static void Main(string[] args)
{
var f = #"\D:\temp\test.xls";
Dos2Unix(f);
}
// Please, note "static"
private static void Dos2Unix(string fileName)
{
...
}
}
Technically, you dont't want Program class instances at all, and so declare the entire class as static:
// class is static
static class Program
{
static void Main(string[] args)
{
var f = #"\D:\temp\test.xls";
Dos2Unix(f);
}
// all methods are static
private static void Dos2Unix(string fileName)
{
...
}
}
You can not call non static method from static method directly, as Main method of Program class is static you can only call static method of program class from this method.
To call a non static method from Main method you can make object of program class and call non static method on this object.
static void Main(string[] args)
{
var f = #"\D:\temp\test.xls";
Program p = new Program();
p.Dos2Unix(f);
}
There is a reason why static method can not call non-static methods as the static method are not tied to instance of that class on the other hand the non-static method is tied to instance (can access the non-static data members). Think a static method calling a non-static method that is accessing instance members that actually does not exist for class, because the static method is called upon class not instance. You can read further in this post.
If you want to call a non-static method from the static method Main, you'll have to create a new object of type Program:
new Program().Dos2Unix(f);
You need to make an instance of your class.
This should work:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
var f = #"\D:\temp\test.xls";
p.Dos2Unix(f);
}
private void Dos2Unix(string fileName)
{
const byte CR = 0x0D;
const byte LF = 0x0A;
byte[] data = File.ReadAllBytes(fileName);
using (FileStream fileStream = File.OpenWrite(fileName))
{
BinaryWriter bw = new BinaryWriter(fileStream);
int position = 0;
int index = 0;
do
{
index = Array.IndexOf<byte>(data, CR, position);
if ((index >= 0) && (data[index + 1] == LF))
{
// Write before the CR
bw.Write(data, position, index - position);
// from LF
position = index + 1;
}
}
while (index > 0);
bw.Write(data, position, data.Length - position);
fileStream.SetLength(fileStream.Position);
}
}
}
}
So basically you only need to add:
Program p = new Program();
and call your method like:
p.Dos2Unix("....");
That's because you can't access a non-static method inside a static method (you can't also use this by the way).
Related
Other methods like Array.Sort() don't use ref and yet they change the array.
Also this code confuses me:
using System.Linq;
using System;
namespace jmennyprostor {
public static void Main(string[] args)
{
int[] mojepole = {4,4,5,2,4};
pole.changearray(mojepole); // this does change mojepole
pole.resizearray(mojepole); // this magically does not change mojepole
pole.resizearrayworking(ref mojepole); // this DOES change mojepole
}
public class pole
{
public static void changearray(int[] polerole)
{
polerole[2] = 44444;
}
public static void resizearray(int[] polerole)
{
Array.Resize(polerole);
}
public static void resizearrayworking(ref int[] polerole)
{
Array.Resize(polerole);
}
}
}
Because the array may not actually be resized. So you pass in a reference to an array of size N, and the method may allocate a new array of size newSize and change your reference to point to the new array.
It has a similar effect as
oldArray = Array.Resize(oldArray, newSize);
if the method returned a reference to the new array instead of using a ref argument.
I have two classes, one for defining the algorithm parameters and another to implement the algorithm:
Class 1 (algorithm parameters):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VM_Placement
{
public static class AlgorithmParameters
{
public static int pop_size = 100;
public static double crossover_rate = 0.7;
public static double mutation_rate = 0.001;
public static int chromo_length = 300;
public static int gene_length = 4;
public static int max_allowable_generations = 400;
static Random rand = new Random();
public static double random_num = rand.NextDouble();
}
}
Class 2 (implement algorithm):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VM_Placement
{
public class Program
{
public struct chromo_typ
{
public string bits;
public float fitness;
//public chromo_typ(){
// bits = "";
// fitness = 0.0f;
//}
chromo_typ(string bts, float ftns)
{
bits = bts;
fitness = ftns;
}
};
public static int GetRandomSeed()
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng =
new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
public string GetRandomBits()
{
string bits="";
for (int i = 0; i < VM_Placement.AlgorithmParameters.chromo_length; i++)
{
if (VM_Placement.AlgorithmParameters.random_num > 0.5f)
bits += "1";
else
bits += "0";
}
return bits;
}
public static void Main(string[] args)
{
Random rnd = new Random(GetRandomSeed());
while (true)
{
chromo_typ[] Population = new chromo_typ[VM_Placement.AlgorithmParameters.pop_size];
double Target;
Console.WriteLine("\n Input a target number");
Target = Convert.ToDouble(Console.ReadLine());
for (int i = 0; i < VM_Placement.AlgorithmParameters.pop_size; i++)
{
Population[i].bits = GetRandomBits();
Population[i].fitness = 0.0f;
}
}
}
}
}
I am getting an error on Population[i].bits = GetRandomBits(); in Main().
Error is:
An object reference is required for the non-static field, method, or property 'VM_Placement.Program.GetRandomBits()'
Am I missing anything?
The Main method is Static. You can not invoke a non-static method from a static method.
GetRandomBits()
is not a static method. Either you have to create an instance of Program
Program p = new Program();
p.GetRandomBits();
or make
GetRandomBits() static.
It looks like you want:
public static string GetRandomBits()
Without static, you would need an object before you can call the GetRandomBits() method. However, since the implementation of GetRandomBits() does not depend on the state of any Program object, it's best to declare it static.
The Main method is static inside the Program class. You can't call an instance method from inside a static method, which is why you're getting the error.
To fix it you just need to make your GetRandomBits() method static as well.
I'm getting an error, "Program does not contain a static 'main' method suitable for an entry point."
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace ConsoleApplication1
{
class Program<T>
{
List<T> a1 = new List<T>();
public void AddData(T data1)
{
a1.Add(data1);
}
public void Insert(T arrayValue, int arrayPosition)
{
// var key = arrayPosition.ToInt();
var key1 = arrayValue.ToString();
for (int i = 0; i < a1.Count; i++)
{
if (i == arrayPosition)
{
a1.Add(arrayValue);
break;
}
}
}
public void Delete(int arrayPosition)
{
for (int i = 0; i < a1.Count; i++)
{
if (i == arrayPosition)
{
a1.Remove(a1[i]);
break;
}
}
}
public void DisplayData()
{
foreach (T x in a1)
{
Console.WriteLine(x);
}
}
static void Main(string[] args)
{
Program<int> obj = new Program<int>();
obj.AddData(123);
obj.AddData(56);
obj.AddData(34);
obj.AddData(87);
obj.DisplayData();
obj.Insert(125, 3);
obj.DisplayData();
obj.Delete(2);
obj.DisplayData();
}
}
}
Per Microsoft documentation (https://learn.microsoft.com/en-us/dotnet/csharp/misc/cs0402) you cannot put your main function in a generic class. It's strange that this was reported as a warning, and the error was less helpful, but that is your problem.
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
public static class Program
{
[STAThread]
public static void Main(string[] args)
{
List<Int32> obj = new List<Int32>();
obj.Add(123);
obj.Add(56);
obj.Add(34);
obj.Add(87);
foreach (Int32 value in obj)
Console.WriteLine(value.ToString());
obj.Insert(3, 125);
foreach (Int32 value in obj)
Console.WriteLine(value.ToString());
obj.RemoveAt(2);
foreach (Int32 value in obj)
Console.WriteLine(value.ToString());
}
}
}
Defining a custom class to handle this tasks looked to me like an overkill. This code should reproduct what you were attempting to do without errors. Anyway, I suggest you to take a look at some basic C# tutorial.
Hope you can help me with this one.i am beginner in multithreading programming with C#.
I am trying to build a program to write all numbers from range 1 to 2000 in two text files using two threads.
Every thread should write number from 1 to 2000 that not found at any of the two files "there is no duplicated numbers in the files" and every thread should't write the number that have been wrote by the another thread.
At the end if we merged the numbers of the two files we should have the numbers from 1 to 2000
Here is the source code i am trying but there is a problem in the writing for loop in the below image
i can't handle the process of writing by the two synchronized threads and i had exception:
Object synchronization method was called from an unsynchronized block of code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace Multithreading
{
class Program
{
static TextWriter file2 = new StreamWriter("file2 location");
static TextWriter file1 = new StreamWriter("file1 location");
static void Main(string[] args)
{
try
{
int[] array = new int[2000];
Thread thread1 = new Thread(Program.writeinfile1);
Thread thread2 = new Thread(Program.writeinfile2);
for (int counter = 1; counter <= 2000; counter++)
{
thread1.Start(counter);
thread2.Start(++counter);
Monitor.Enter(thread1);
Monitor.Wait(thread1);
Monitor.PulseAll(thread2);
}
}
catch (FileNotFoundException)
{
Console.WriteLine("the file you are trying to open is not found");
}
}
public static void writeinfile1(object x)
{
int converttointx = (int)x;
file1.WriteLine(converttointx);
file1.Close();
}
public static void writeinfile2(object y)
{
int converttointy = (int)y;
file2.WriteLine(converttointy);
file2.Close();
}
}
}
Here's an example of multi-threaded calls talking to one another to ensure they don't duplicate work.
I've not done exactly what you've asked for, since this looks quite homeworky; but hopefully this will help you to figure out the solution to your issue...
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace StackOverflow
{
class Program
{
static void Main(string[] args)
{
new Program();
Console.WriteLine("done");
Console.ReadKey();
}
Program()
{
int noThreads = 5;
int target = 2000;
StartThread(noThreads, target);
}
//kicks off our threads / waits for all threads to complete before returning
void StartThread(int noThreads, int target)
{
int id = noThreads--;
if (id > 0)
{
Doer doer = new Doer(id, target);
Thread t = new Thread(doer.Do);
t.Start();
StartThread(noThreads,target);
t.Join();
}
}
}
class Doer
{
static int marker = 0;
static readonly object syncLocker = new object();
readonly int id;
readonly int target;
public Doer(int id, int target)
{
this.id = id;
this.target = target;
}
public void Do()
{
while (marker < this.target)
{
int i;
lock (syncLocker)
{
i = ++marker;
}
System.Console.WriteLine("{0:00}: {1:###0}", id, i);
//Thread.Sleep(RandomNo()); //uncomment this & code below if your threads are taking turns / behaving too predictably
}
}
/*
static readonly Random rnd = new Random();
static readonly object rndSyncLocker = new object();
public static int RandomNo()
{
lock (rndSyncLocker)
{
return rnd.Next(0, 1000);
}
}
*/
}
}
You are not using the Monitor class correctly. The call to Monitor.PulseAll(thread2); should be called within thread the thread which owns the lock, which in this case would be within the writeinfile1 and writeinfile2 method.
This is why you are getting the exception:
Object synchronization method was called from an unsynchronized block of code.
See the following StackOverflow question for the correct way to use Monitor.PulseAll(object):
Help needed in Monitor.PulseAll()
I am coding a rcon message tool for a game server in C#. However I've run across a error:
"The name 'm' does not exist in the current context"
By now you're shouting at your screen NOOB! and yes I admit I am; I have little real coding experience.
I've played with MFC C++ and OpenGL and I'm a fairly respected cod modder "script is gsc loosely based on c++" so I hope I can learn quickly, basically I tried to access an instance of b. outside of the main loop but it gave me the error:
The name b does not exist in the current context
so I made a new messages function that started a new connection in a new instance. Then I tried the access that in another function stopmessages() but I still get the error.
Sorry for the newb question. I've googled long and hard about this and I just don't understand.
Here's my code - it uses Nini.dll for config file access and BattleNET.dll for access to rcon for the game -
#region
using System;
using System.Net;
using System.Text;
using BattleNET;
using Nini.Config;
#endregion
namespace BattleNET_client
{
internal class Program
{
private static void Main(string[] args)
{
bool isit_ok = true;
Console.OutputEncoding = Encoding.UTF8;
Console.Title = "rotceh_dnih's DayZ servermessages";
BattlEyeLoginCredentials loginCredentials = GetLoginCredentials();
Console.Title += string.Format(" - {0}:{1}", loginCredentials.Host, loginCredentials.Port);
IBattleNET b = new BattlEyeClient(loginCredentials);
b.MessageReceivedEvent += DumpMessage;
b.DisconnectEvent += Disconnected;
b.ReconnectOnPacketLoss(true);
b.Connect();
while (true)
{
startmessages();
string cmd = Console.ReadLine();
if (cmd == "exit" || cmd == "logout" || cmd == "quit")
{
Environment.Exit(0);
}
if (cmd == "restart")
{
stopmessages();
}
if (cmd == "startstuff")
{
startmessages();
}
if (b.IsConnected())
{
if (isit_ok)
{
}
isit_ok = false;
b.SendCommandPacket(cmd);
}
else
{
Console.WriteLine("Not connected!");
}
}
}
private static BattlEyeLoginCredentials GetLoginCredentials()
{
IConfigSource source = new IniConfigSource("server/admindets.ini");
string serverip = source.Configs["rconlogin"].Get("ip");
int serverport = source.Configs["rconlogin"].GetInt("port");
string password = source.Configs["rconlogin"].Get("rconpwd");
var loginCredentials = new BattlEyeLoginCredentials
{
Host = serverip,
Port = serverport,
Password = password,
};
return loginCredentials;
}
public static void startmessages()
{
BattlEyeLoginCredentials loginCredentials = GetLoginCredentials();
IBattleNET m = new BattlEyeClient(loginCredentials);
m.MessageReceivedEvent += DumpMessage;
m.DisconnectEvent += Disconnected;
m.ReconnectOnPacketLoss(true);
m.Connect();
IConfigSource messagesource = new IniConfigSource("messages/servermessages.ini");
int messagewait = messagesource.Configs["timesettings"].GetInt("delay");
string[] messages = messagesource.Configs["rconmessages"].Get("messages1").Split('|');
// for (;;)
// {
foreach (string message in messages)
{
Console.WriteLine(message);
m.SendCommandPacket(EBattlEyeCommand.Say,message);
System.Threading.Thread.Sleep(messagewait * 60 * 1000);
}
// }
}
public static void stopmessages()
{
m.Disconnect();
}
private static void Disconnected(BattlEyeDisconnectEventArgs args)
{
Console.WriteLine(args.Message);
}
private static void DumpMessage(BattlEyeMessageEventArgs args)
{
Console.WriteLine(args.Message);
}
}
}
You need to put the declaration of m into the class scope:
internal class Program
{
// declare m as field at class level
private static IBattleNET m;
private static void Main(string[] args)
{
....
}
public static void startmessages()
{
BattlEyeLoginCredentials loginCredentials = GetLoginCredentials();
// JUST SET THE VALUE HERE
m = new BattlEyeClient(loginCredentials);
m.MessageReceivedEvent += DumpMessage;
m.DisconnectEvent += Disconnected;
m.ReconnectOnPacketLoss(true);
m.Connect();
IConfigSource messagesource = new IniConfigSource("messages/servermessages.ini");
int messagewait = messagesource.Configs["timesettings"].GetInt("delay");
string[] messages = messagesource.Configs["rconmessages"].Get("messages1").Split('|');
// for (;;)
// {
foreach (string message in messages)
{
Console.WriteLine(message);
m.SendCommandPacket(EBattlEyeCommand.Say,message);
System.Threading.Thread.Sleep(messagewait * 60 * 1000);
}
// }
}
The stopmessages() method won't be able to access m as the variable m only exists within the startmessages() method
Move the declaration of IBattleNET m
To outside the main function and make it static:
static IBattleNet b;
Then in your main you just do m = new BattlEyeClient(loginCredentials);
m is declared in scope of static method startmessages but then you are trying to use it in stopmessages, where it is not in scope. You should move the variable to class scope, and define it as static (since your methods are static).
Hopefully your client app is single-threaded, otherwise you will need to consider thread safety issues as well.
what you could do is after you declared your class, so bevore the static void main
declare your m value
internal class Program
{
IBattleNET m;
then in the startMessages method add
m = new BattlEyeClient(loginCredentials);
this will make the m value available to all the methods inside your class
I'm assuming m should refer to this:
IBattleNET m = new BattlEyeClient(loginCredentials);
in the method startmessages(). What you need to do is declare IBattleNET m outside the method body:
static IBattleNET m;
public static void startmessages()
{
//etc