I'm very new to C#. Coming from pure C/C++ background. Hence please go easy on me, if my question is basic.
I'm trying to declare an object of struct Abc which is complaining a compilation error as below which means that, the object obj is NOT recognized.
string mains1 = obj.s1;
error CS0120: An object reference is required for the non-static
field, method, or property 'csharp1.Program.obj'
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace csharp1
{
class Program
{
public struct Abc
{
public string s1;
};
Abc obj = new Abc();;
static void Main(string[] args)
{
System.Console.WriteLine("start main");
string cwd = Directory.GetCurrentDirectory();
string fileName = "Myfile.xml";
string destFile = System.IO.Path.Combine(cwd, fileName);
string inpFile = "MyfileINP.xml";
string inpDir = System.IO.Path.Combine(cwd, "SubDir");
string srcfile = System.IO.Path.Combine(inpDir,inpFile);
File.Copy(srcfile, destFile, false);
string mains1 = obj.s1;
}
}
}
Not sure what is the error here.
This is complaining because you are trying to access a non static instance "obj" from a static context the Main method so there are multiple ways to resolve it you can make that instance static too like "static Abc obj=new Abc()" or you can shift that declaration inside Main method or you can create an instance of Program class and then use that instance.
METHOD 1:
static Abc obj = new Abc();
static void Main(string[] args)
{
System.Console.WriteLine("start main");
//
string mains1 = obj.s1;
}
METHOD 2:
static void Main(string[] args)
{
Abc obj = new Abc();
System.Console.WriteLine("start main");
//
string mains1 = obj.s1;
}
METHOD 3:
Abc obj = new Abc();
static void Main(string[] args)
{
System.Console.WriteLine("start main");
//
string mains1 = new Program().obj.s1;
}
Its always not a good practice to make "static" everywhere until
there is no other option you have, making static allow this object to
be shared across all the instances of this class so its not good thing
until we really need that.
You need to create an instance of the containing class Program before accessing it's member(s) like
string mains1 = new Program().obj.s1;
You are trying to access obj (a non-static method) from within Main (a static method). Because of this, your are getting CS0120. I advise changing Abc obj = new Abc() to static ABC obj = new Abc().
Related
I have an issue with creating lists in C#. It says that the type or namespace "file<>" could not be found. I am using System.Collections.Generic and creating the list "correct" as far as I know.
I have basically nothing yet besides the list (worked with array earlier but it didn't meet the requirements):
using System;
using System.IO;
using System.Collections.Generic;
namespace Week_3_Opdracht_3
{
class Program
{
public list<string> streamReaderResults = new list<string>();
private static string currentFileLine;
static void Main(string[] args)
{
StreamReader opdrachtDrieFile = new StreamReader(#"C:\Users\sande\Documents\VisualStudio school\.txt files to read\Opdracht 3 tekst.txt");
while ((currentFileLine = opdrachtDrieFile.ReadLine()) != null)
{
//nothing yet.
}
Console.ReadKey();
}
}
}
From what I know, you create a list by typing "list [name of the list] = new list();". However, this doesn't work. Why am I receiving this error message?
C# is a case-sensitive language, so you need to watch casing. Also, Main in your program is a static method, and can only access static members of the Program class. So you need to mark the List<T> as static:
namespace Week_3_Opdracht_3
{
class Program
{
public static List<string> streamReaderResults = new List<string>();
private static string currentFileLine;
static void Main(string[] args)
{
StreamReader opdrachtDrieFile = new StreamReader(#"C:\Users\sande\Documents\VisualStudio school\.txt files to read\Opdracht 3 tekst.txt");
while ((currentFileLine = opdrachtDrieFile.ReadLine()) != null)
{
//nothing yet.
}
Console.ReadKey();
}
}
}
You need to make list to static.
public static List<string> streamReaderResults = new List<string>();
I am attempting to make an application which gets and inputted URL via textbox, retrieves the HtmlCode of that website when a button is clicked and stores both in a dictionary which is then displayed in a listbox.
However, I haven't been able to implement any of it into the user interface yet due to having an issue when trying to add an entry to the dictionary. To retrieve the HtmlCode I am calling the method GetHtml however, i am getting an error when trying to add the website and the code to the dictionary.
Code Follows
namespace HtmlCheck
{
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());
var dict = new SortedDictionary<string, WebsiteInfo>();
var list = (from entry in dict
orderby entry.Key
select entry.Key).ToList();
}
private static void addPerson(string websiteUrl)
{
dict.Add(websiteUrl, new WebsiteInfo { WebsiteUrl = websiteUrl, HtmlCode = getHtml(websiteUrl) });
}
private static SortedDictionary<string, WebsiteInfo> dict;
public string getHtml(string websiteUrl)
{
using (WebClient client = new WebClient())
return client.DownloadString(websiteUrl);
}
}
public class WebsiteInfo
{
public string WebsiteUrl;
public string HtmlCode;
public override string ToString()
{
string formated = string.Format("{0}\n---------------------------------- \n{1}", WebsiteUrl, HtmlCode);
return formated;
}
}
}
In the method
private static void addPerson(string websiteUrl)
{
dict.Add(websiteUrl, new WebsiteInfo { WebsiteUrl = websiteUrl, HtmlCode = getHtml(websiteUrl) });
}
the HtmlCode = getHtml(websiteUrl) is throwing an error:
"An object reference is required for the non-static field, method, or property 'HtmlCheck.Program.getHtml(string)'"
So my question is, why cant I add an entry to the dictionary with this information?
Thanks for your time.
You're getting that error because addPerson() is a static method (it is called without creating an instance of the Program class), but the getHtml() method is not static (so you need an instance of the Program class to call it).
Easy fix - make it static too:
public static string getHtml(string websiteUrl)
{
...
}
For the sake of completeness, you'd have to otherwise create an instance of the Program class before calling the getHtml() method:
private static void addPerson(string websiteUrl)
{
var p = new Program();
dict.Add(websiteUrl, new WebsiteInfo { WebsiteUrl = websiteUrl, HtmlCode = p.getHtml(websiteUrl) });
}
addPerson() is a static method, which means you can call it any time, without having an instance of the class to call it on. It then tries to call getHtml(), which is non-static, which means it can only be called through a valid instance of the class.
I suggest you do some research on static methods in C# to get your head around this.
Add "static" to your method;
public static string getHtml(string websiteUrl)
I'm looking to move a scripting solution that I currently have over to C# as I believe as this will solve some of the issues which I am currently facing when it comes to running on different platforms. I can call functions which are within the script and access their variables, however, one thing that I would like to be able to do is call a function from the class that the script resides in. Does anyone know how I would be able to do this?
Here is my code at the minute which is working for calling and access objects within the script, but I would like to be able to call the method "Called" from within the script, but cannot:
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.CSharp;
namespace scriptingTest
{
class MainClass
{
public static void Main (string[] args)
{
var csc = new CSharpCodeProvider ();
var res = csc.CompileAssemblyFromSource (
new CompilerParameters ()
{
GenerateInMemory = true
},
#"using System;
public class TestClass
{
public int testvar = 5;
public string Execute()
{
return ""Executed."";
}
}"
);
if (res.Errors.Count == 0) {
var type = res.CompiledAssembly.GetType ("TestClass");
var obj = Activator.CreateInstance (type);
var output = type.GetMethod ("Execute").Invoke (obj, new object[] { });
Console.WriteLine (output.ToString ());
FieldInfo test = type.GetField ("testvar");
Console.WriteLine (type.GetField ("testvar").GetValue (obj));
} else {
foreach (var error in res.Errors)
Console.WriteLine(error.ToString());
}
Console.ReadLine ();
}
static void Called() // This is what I would like to be able to call
{
Console.WriteLine("Called from script.");
}
}
}
I am attempting to do this in Mono, however, I don't believe this should affect how this would be resolved.
There are a handful of things you need to change.
MainClass and Called need to be accessible to other assemblies so make them public. Additionally, you need to add a reference to the current assembly to be able to access it in your script code. So essentially your code will end up looking like:
public class MainClass
public static void Called()
var csc = new CSharpCodeProvider();
var ca = Assembly.GetExecutingAssembly();
var cp = new CompilerParameters();
cp.GenerateInMemory = true;
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("mscorlib.dll");
cp.ReferencedAssemblies.Add(ca.Location);
var res = csc.CompileAssemblyFromSource(
cp,
#"using System;
public class TestClass
{
public int testvar = 5;
public string Execute()
{
scriptingTest.MainClass.Called();
return ""Executed."";
}
}"
);
The output of running the test looks like:
Called from script.
Executed.
5
I want to invoke the method by the method name stored in the list. Can anyone help? I'm new to c#!
{
delegate string ConvertsIntToString(int i);
}
class Program
{
public static List<String> states = new List<string>() { "dfd","HiThere"};
static void Main(string[] args)
{
ConvertsIntToString someMethod = new ConvertsIntToString(states[1]);
string message = someMethod(5);
Console.WriteLine(message);
Console.ReadKey();
}
private static string HiThere(int i)
{
return "Hi there! #" + (i * 100);
}
}
It looks like you don't need Delegate.DynamicInvoke at all - you're not trying to invoke it dynamically - you're trying to create the delegate dynamically, which you can do with Delegate.CreateDelegate. Short but complete program based around your example (but without using a list - there's no need for that here):
using System;
using System.Reflection;
delegate string ConvertsIntToString(int i);
class Program
{
static void Main(string[] args)
{
// Obviously this can come from elsewhere
string name = "HiThere";
var method = typeof(Program).GetMethod(name,
BindingFlags.Static |
BindingFlags.NonPublic);
var del = (ConvertsIntToString) Delegate.CreateDelegate
(typeof(ConvertsIntToString), method);
string result = del(5);
Console.WriteLine(result);
}
private static string HiThere(int i)
{
return "Hi there! #" + (i * 100);
}
}
Obviously you need to adjust it if the method you want is in a different type, or is an instance method, or is public.
I need to dynamically load an interface assembly that I use on client-side remoting. Something like this.
static void Main(string[] args)
{
TcpClientChannel clientChannel = new TcpClientChannel();
ChannelServices.RegisterChannel(clientChannel, false);
Assembly interfaceAssembly = Assembly.LoadFile("RemotingInterface.dll");
Type iTheInterface =
interfaceAssembly.GetType("RemotingInterface.ITheService");
RemotingConfiguration.RegisterWellKnownClientType(iTheInterface,
"tcp://localhost:9090/Remotable.rem");
object wellKnownObject = Activator.GetObject(iTheInterface,
"tcp://localhost:9090/Remotable.rem");
}
Only I can't seem to grasp how to call any methods as I can't cast the Activator.GetObject. How can I create a proxy of ITheService without knowing the interface at compile-time?
Got an answer from MSDN forums.
static void Main(string[] args)
{
TcpClientChannel clientChannel = new TcpClientChannel();
ChannelServices.RegisterChannel(clientChannel, false);
Assembly interfaceAssembly = Assembly.LoadFile("RemotingInterface.dll");
Type iTheInterface = interfaceAssembly.GetType("RemotingInterface.ITheService");
RemotingConfiguration.RegisterWellKnownClientType(iTheInterface,
"tcp://localhost:9090/Remotable.rem");
object wellKnownObject = Activator.GetObject(iTheInterface,
"tcp://localhost:9090/Remotable.rem");
MethodInfo m = iTheInterface.GetMethod("MethodName");
m.Invoke(wellKnownObject, new object[] { "Argument"});
}
The returned object implements the interface, so you can use reflection to get its member methods and invoke them.
Or, in C#4, you can use dynamic:
dynamic wellKnownObject = Activator.GetObject(iTheInterface,
"tcp://localhost:9090/Remotable.rem");
wellKnownObject.SomeMethod(etc ..);
First, inspect the available methods/interfaces of your object:
object wellKnownObject =
Activator.GetObject(iTheInterface, "tcp://localhost:9090/Remotable.rem");
var objType = wellKnownObject.GetType();
var methods = objType.GetMethods();
var interfaces = objType.GetInterfaces();
After you're sure about the method you want to invoke,
Consider using DLR and/or wrap the dynamic object in a DynamicObject container.
Use methods[i].Invoke on the object.
Here are some examples:
namespace ConsoleApplication1
{
using System;
class Program
{
static void Main()
{
//Using reflection:
object obj = GetUnknownObject();
var objType = obj.GetType();
var knownInterface = objType.GetInterface("IA");
var method = knownInterface.GetMethod("Print");
method.Invoke(obj, new object[] { "Using reflection" });
//Using DRL
dynamic dObj = GetUnknownObject();
dObj.Print("Using DLR");
//Using a wrapper, so you the dirty dynamic code stays outside
Marshal marshal = new Marshal(GetUnknownObject());
marshal.Print("Using a wrapper");
}
static object GetUnknownObject()
{
return new A();
}
} //class Program
class Marshal
{
readonly dynamic unknownObject;
public Marshal(object unknownObject)
{
this.unknownObject = unknownObject;
}
public void Print(string text)
{
unknownObject.Print(text);
}
}
#region Unknown Types
interface IA
{
void Print(string text);
}
class A : IA
{
public void Print(string text)
{
Console.WriteLine(text);
Console.ReadKey();
}
}
#endregion Unknown Types
}
Can I get the Interface information from the remoting URL like http://localhost:8080/xxx.rem?wsdl.
As WebService, I can get the interface information from the service url, http://xXX.xx.xxx.xx/url.svc?wsdl, and compile the assembly by myself code, and invoke methods via reflection.