I have a function in a utility class
namespace GUI.code
{
public class Utility
{
public string GetFileName(string grpID)
{
string filenameUNC = "\\\\" + "localhost" + "\\AgentShare\\";
string realPath = GetPath(filenameUNC);
return realPath;
}
}
}
now i call this function from another page in the project like this:
new utility.GetCSFileName(ID);
why do i need to add new, why cant i call it like
GetCSFileName(ID);
when i have
using GUI.code;
on top
if i remove new i get this error
Error 1 An object reference is required for the non-static field, method, or property 'copiunGUI.code.GUIUtility.GetCSFileName(string)
any suggestions
You can call Utility.GetFileName() if you change the declaration to public static string GetFileName(string grpID)
static means that the member is shared among all instances of the Utility class. Remember, c# is an object-oriented language. Non-static members are called instance members, and must be called on a distinct instance of the class. Each time you call new Utility(), you are creating such an instance, and this is distinct from every other.
This is useful when each instance of a class needs to maintain information (state) internally. If, however, a particular member does not use state data -- it accepts parameters, does work, and optionally returns a result -- it can be declared static. Then you call it not from the instance variable but from the class name itself (in this case Utility.GetFileName().
When all of the members of a class are static, you can add static to the class declaration itself. At that point, you would never be able to call new Utility(), which might be what you want in this case.
You need to mark your method as static.
public class Utility
{
public static string GetFileName(string grpID)
{
string filenameUNC = "\\\\" + "localhost" + "\\AgentShare\\";
string realPath = GetPath(filenameUNC);
return realPath;
}
}
You will then be able to call your method with Utility.GetFileName(...)
Read more on static methods / classes here.
It looks like you want to mark your method (and possibly your class also) as static:
public static class Utility
{
public static string GetFileName(string grpID)
...
Then you can call it like this:
string filename = Utility.GetFileName(ID);
Make the method static and you can use it without an instance of the class
eg
public static string GetFileName(string grpID)
usage:
Utility.GetCSFileName(ID);
You don't have to have a new one, if you set up your method as a static method:
public static string GetFileName(string grpID)
{
//your code here
}
Then you still have to call the Class name, but you don't have to instantiate it:
so instead of:
Utility util = new Utility();
util.GetFileName("myString");
you can do:
Utility.GetFileName("myString");
And the reason you can't do just GetFileName("myString") is that you're not calling it from inside the class where it's defined.
When a method is marked with the static keyword it means that you don't have to create a new instance of the object (using 'new') to call the method, as you intend.
One thing to watch out for is that if you mark a method as being static, it cannot call any non-static methods, only static ones. You also can't use any properties of the object that are non-static.
the trick is to define method as static. This will do it:
namespace GUI.code
{
public class Utility
{
public static string GetFileName(string grpID)
{
string filenameUNC = "\\\\" + "localhost" + "\\AgentShare\\";
string realPath = GetPath(filenameUNC);
return realPath;
}
}
}
now you can write utility.GetCSFileName(ID);.
But you still have to mention class.
Related
I understand that we could use the class name.method but I was wondering if there was a way to do it through an instance. Can you provide me an example also. The reason I'm asking is because my professor said:
You MUST invoke the extension method using calls that use the static
call form and the instance call form
With the edit that this is talking about extension methods, then it becomes easier!
With the same example as below:
bool hasValue1 = s.HasValue(); // use the instance syntax
bool hasValue2 = StringExtensions.HasValue(s); // use the static syntax
Note that these are 100% identical; once compiled to IL you cannot determine which form was used.
Short answer: "no", per CS0176:
CS0176 Member '{name}' cannot be accessed with an instance reference; qualify it with a type name instead
Slightly longer answer: if you really want to do that, maybe extension methods are what you are looking for; for example:
static class StringExtensions
{
public static bool HasValue(this string value)
{
return !string.IsNullOrEmpty(value);
}
}
class Program
{
static void Main()
{
string s = /* some string or null reference */
bool hasValue = s.HasValue();
}
}
I've come across this piece of code where it looks like the original developer has tried to use a static string to cache a value in a static class.
public static class GetStringFromSomeProcess
{
private static string theAnswer;
public static string GetString
{
get
{
if(theAnswer == null)
{
theAnswer = GoGetTheAnswerFromALongRunningProcess();
}
return theAnswer;
}
}
}
As far as I can see this won't work, as you can't instantiate the GetStringFromSomeProcess class, GoGetTheAnswerFromALongRunningProcess will be called every time GetString is used. Am I missing something?
This will work fine - there is only one instance of theAnswer because it is static - and (also because it is static) it can be accessed from a public static property. This means that any changes made to it will be visible to all code that accesses it. So the first call to GetString will set theAnswer to non-null, and subsequent calls will not make a call to GetStringFromSomeProcess().
However, the solution you posted is not threadsafe because GoGetTheAnswerFromALongRunningProcess() could be called simultaneously by multiple threads.
.Net provides the Lazy class to solve this issue, as follows:
public static class GetStringFromSomeProcess
{
private static readonly Lazy<string> _theAnswer = new Lazy<string>(GoGetTheAnswerFromALongRunningProcess);
public static string GetString
{
get
{
return _theAnswer.Value;
}
}
public static string GoGetTheAnswerFromALongRunningProcess()
{
return "X";
}
}
You supply to the constructor of the Lazy<T> class a method that it can call when needed in order to create the object that it is wrapping. In the example above, I pass GoGetTheAnswerFromALongRunningProcess to its constructor.
Also note that it's usually a bad idea to have a property that can take a very long time to return. It's better to make it a method:
public static string GetString()
{
return _theAnswer.Value;
}
You are right in saying that the class can't be instantiated, but the class will exist within the application.
Therefore, only the first time the property is accessed, will the method GetStringFromSomeProcess be called. Every other time after that, the check for == null will resolve to false and the value evaluated by the first call will be returned.
Does it work correctly without creating an object of the GetStringFromSomeProces class? Since the string, theAnswer, is also static, it could potentially work, but I'm wondering when that variable will be initialized. Typically you would code it like you are suggesting with initialization of the GetStringFromSomeProcess Class.
Main.cs
...
GetStringFromSomeProcess getString = new GetStringFromSomeProcess();
string answer = getString.theAnswer();
...
GetStringFromSomeProcess.cs
public class GetStringFromSomeProcess
{
private string _theAnswer;
public string theAnswer
{
get
{
if(theAnswer == null)
{
GoGetTheAnswerFromALongRunningProcess getAnswer = new GoGetTheAnswerFromALongRunningProcess();
_theAnswer = getAnswer.GetAnswer();
}
return _theAnswer;
}
}
}
I have a user_name defined above in class Form1 : Form
And user_name is defined above as,
string user_name = "Rammy";
and i want to use this user_name in below line, but it is not executing, and giving error "A field initializer cannot reference the non-static field, method, or property".
string copyright_bottom_text = user_name;
Can someone please help with this? I am using visual studio 2012.
move below line to a constructor or method
string copyright_bottom_text = user_name;
Compiler Error CS0236
Instance fields cannot be used to initialize other instance fields
outside a method. If you are trying to initialize a variable outside a
method, consider performing the initialization inside the class
constructor. For more information, see Methods (C# Programming Guide).
public class MyClass
{
public int i = 5;
public int j = i; // CS0236
public int k; // initialize in constructor
MyClass()
{
k = i;
}
public static void Main()
{
}
}
You probably try to access the user_name variable from a static method.
There are static and instance variables/methods. Static ones belongs to the class itself, and don't belong to instances created from that class. All instances an access the data through the class, but if you change it, it will change for all the instances -of course because it belongs to the class.
This is how it looks like:
class Something {
private static string StaticString = "I belong to the class";
...
//constructor
...
}
Then, when you make a instance of this class:
Something s = new Something();
You can't say
string x = s.StaticString;
because it belongs to the class "Something", not the instance "s".
You can say however
string x = Something.StaticString;
In your example, you try to reach a instance variable, from a static method. This is the opposite of the above:
the user_name is unique in each instance (say, You can have a instance with name Joe, a instance with name Robert, etc). But you try to use it on a class level. The class doens't know anything about instances created based on it.
It's like when you give your dog a name, all dog should be called the same. It's not working.
Try to use static string as user_name, so it will compile, but it won't be correct.
Instead, keep the variable as a instance variable (not static), and use it in instance methods (not static). Keep in mind that you CAN use static methods and variables in instance methods, but you can't use instance variables or methnds in static methods.
I hope that helped. :)
I have a Sealed class in C#, which already exists and all methods are static.
It does some file operations with xml file. The file name till today was hardcoded into source.
Now the requirement needs to keep it in Configuration file.
The problem is:
Since class is extract, i need to expose some static 'Initialize' method to assign filename to some local static filename variable, which will replace hardcoded string.
So, i always have to make sure, Initialize is called first and then later method.
So, the better way is to have constructor, which i cant write.
I want a better way to do this ensuring type safety.
If the filename field is static, you could make it a property or method and make sure the getter does the work of initializing it from the configuration file if it is not already initialized...
That way you don't have to explicitly initialize the class via a method you can have the access to the property itself initialize the value.
Something like below..
static string FileName { get { return (_field ?? _field = GetFileName()); } }
static string GetFileName() { /* TODO: Return filename from config */ }
Why can't you use a static constructor?
You could write a static constructor to initialize your paths before the static members are referenced.
More info can be found here
If the class itself doesn't know how to access the config I'd use a one time setter:
private static string _filename;
public static string Filename
{
get
{
if(_filename==null)
throw new InvalidOperationException("Filename not set");
return _filename;
}
set
{
if(_filename!=null)
throw new InvalidOperationException("Filename set twice");
_filename=value;
}
}
Or if the class can access the config directly it's even easier:
private static readonly string Filename;
static MyClassName()
{
Filename=GetFilenameFromConfig();
}
Just initialize it in a static constructor.
Assuming the configuration file path is known (i.e. the class takes no formal arguments), then a static constructor might help.
You could change your current class from something like:-
public static Foo
{
public static void Execute()
{
const string FileName = "foo.xml";
// ...
}
}
To something like
public static Foo
{
public static void Execute()
{
Execute("foo.xml");
}
public static void Execute(string fileName)
{
// ...
}
}
Current clients of the code can continue to use the original method (hard coded file name) and any new clients which have the file name as a configuration item can use the new method which takes the file name as a parameter. Or, if you have decided that all client should use the new method, then you can change them to do that and remove the old method.
The simplest option would be to add a static constructor. That will be executed before any other code:
public static class Foo
{
static Foo()
{
// Initialization code
}
// Other methods which can depend on initialization code having run
}
As I say, this is the simplest - in terms of changes to your existing code. However, code like this tends to be hard to debug, and if you have a lot of static constructors which depend on each other, you can get into some tricky situations (particularly if you have cyclic dependencies). For an example of this, watch the "C# Puzzlers" video from NDC 2010 - an excellent talk given by Eric Lippert and Neal Gafter.
How is it possible to make prototype methods in C#.Net?
In JavaScript, I can do the following to create a trim method for the string object:
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g,"");
}
How can I go about doing this in C#.Net?
You can't dynamically add methods to existing objects or classes in .NET, except by changing the source for that class.
You can, however, in C# 3.0, use extension methods, which look like new methods, but are compile-time magic.
To do this for your code:
public static class StringExtensions
{
public static String trim(this String s)
{
return s.Trim();
}
}
To use it:
String s = " Test ";
s = s.trim();
This looks like a new method, but will compile the exact same way as this code:
String s = " Test ";
s = StringExtensions.trim(s);
What exactly are you trying to accomplish? Perhaps there are better ways of doing what you want?
It sounds like you're talking about C#'s Extension Methods. You add functionality to existing classes by inserting the "this" keyword before the first parameter. The method has to be a static method in a static class. Strings in .NET already have a "Trim" method, so I'll use another example.
public static class MyStringEtensions
{
public static bool ContainsMabster(this string s)
{
return s.Contains("Mabster");
}
}
So now every string has a tremendously useful ContainsMabster method, which I can use like this:
if ("Why hello there, Mabster!".ContainsMabster()) { /* ... */ }
Note that you can also add extension methods to interfaces (eg IList), which means that any class implementing that interface will also pick up that new method.
Any extra parameters you declare in the extension method (after the first "this" parameter) are treated as normal parameters.
You need to create an extension method, which requires .NET 3.5. The method needs to be static, in a static class. The first parameter of the method needs to be prefixed with "this" in the signature.
public static string MyMethod(this string input)
{
// do things
}
You can then call it like
"asdfas".MyMethod();
Using the 3.5 compiler you can use an Extension Method:
public static void Trim(this string s)
{
// implementation
}
You can use this on a CLR 2.0 targeted project (3.5 compiler) by including this hack:
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
public sealed class ExtensionAttribute : Attribute
{
}
}