how to call static method inside non static method through instance - c#

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

Related

Can a static member variable be used to cache a value in a static class?

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

How to trigger a static constructor

code:
class Base<T,U> where T:Base<T,U>,new() where U :class
{
protected static U _val = null;
internal static void ShowValue()
{
if(_val == null)new T(); //Without this line, it won't work as expected
Console.WriteLine (_val);
}
internal static void Virtual()
{
Console.WriteLine ("Base");
}
}
class Deriv :Base<Deriv,string>
{
static Deriv()
{
_val = "some string value";
}
internal static new void Virtual ()
{
Console.WriteLine ("Deriv");
}
}
public static void Main (string[] args)
{
Deriv.ShowValue();
Deriv.Virtual();
}
Thanks to the generics of .NET, I can create a bunch of specific classes reusing generic static methods defined in the generic base class. It can mimic inheritance polymorphism to some extent. But in order to initialize different version of static fields, I've to use static constructors. Unfortunately, we can't call them directly, therefore, we have to figure out a way to trigger it's invocation. The example given above showed a way. But I don't like either the instantiation,or the reflection approach. We also can't make a constraint on a static method of a generic parameter. So, I'd like to ask, if there is another way to do this kind of job!
Thanks beforehand!
~~~~~~~~~~~~~~~~
Some Conclusion (Maybe a little early):
It seems there is no workaround to deal with this kind of situation. I have to instantiate a subclass or use reflection. Considering the .cctors need merely be called once, I'm in favor of the reflection approach, because in some case, a new() constraint is just not a choice - like you're not supposed to expose the parameterless ctor to user.
After conducting further experiment, I find out that the .cctors may be called multi-times but only the first invocation will affect the setting of static fields. That's weird, but a good weirdness!
class MyClass
{
static int _val = 0;
static MyClass()
{
_val++;
Console.WriteLine (_val);
}
}
public static void Main (string[] args)
{
ConstructorInfo ci = typeof(MyClass).TypeInitializer;
ci.Invoke(new object[0]);
ci.Invoke(new object[0]);
ci.Invoke(new object[0]);
}
//result:
//1
//1
//1
//1
I would strongly advise you to rethink your design. Attempting to use this sort of workaround for "static inheritance" is fighting against some of the core designs of .NET.
It's unclear what bigger problem you're trying to solve, but trying "clever" code like this to simulate inheritance will lead to code which is very hard to maintain and diagnose in the longer term.
Without actually using a member of Deriv (or creating an instance of it), you basically won't trigger the static constructor. It's important to understand that Deriv.ShowValue() is basically converted into a call to
Base<Deriv, string>.ShowValue();
... so you're not actually calling anything on Deriv. Your calling code would actually be clearer if it were written that way.
EDIT: One other (clearly unfortunate) reason to avoid using type initializers explicitly is that there's a bug in .NET 4.5 which causes an exception to be thrown inappropriately in some cases. See my question on the topic for more information.
The correct solution is to invoke the type initializer (= static constructor) like this:
typeof(T).TypeInitializer.Invoke(null, null);
It needs both nulls. Specifying only one gives a MemberAccessException.
Thus, your code might want to look something like this:
internal static void ShowValue()
{
if (_val == null)
{
if (typeof(T).TypeInitializer != null)
typeof(T).TypeInitializer.Invoke(null, null);
if (_val == null)
throw new InvalidOperationException(string.Format("The type initializer of {0} did not initialize the _val field.", typeof(T)));
}
Console.WriteLine(_val);
}
And with that, you can remove the new() constraint.
You have no control of when the static constuctor will execute, but what is guaranteed is that it will run before accessing any static property or method and before instantiation.
There is really no reason to want the static constructor to execute at an earlier point. If you are not using anything from the class but you want the code in the static constructor to run, then something is wrong in your design.
Static constructors are automatically, only once. You cannot call them yourself.
An example from here:
public class Bus
{
// Static constructor:
static Bus()
{
System.Console.WriteLine("The static constructor invoked.");
}
public static void Drive()
{
System.Console.WriteLine("The Drive method invoked.");
}
}
class TestBus
{
static void Main()
{
Bus.Drive();
}
}
output:
The static constructor invoked.
The Drive method invoked.
I direct you to the MSDN article on Static Constructors and about 10% down the page:
A static constructor is called automatically to initialize the class
before the first instance is created or any static members are
referenced.

Implementation Problem with Static Sealed Class

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.

call a function in utility class

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.

Invoking non static method from static method

Can I call(access) non static method from static method ??
Like I have static method If yes, how??
public static void method() //like this is a static method
{
methodsec(); //from here I want to access non static method defined below
}
public void methodsec() // non static method
{
}
Yes, but you need a reference to do it through:
public static void StaticMethod()
{
someInstance.InstanceMethod();
}
public void InstanceMethod()
{
}
You need to think about which instance you want to call the method on. Instance methods typically use the state of the instance, so the method is likely to do different things depending on which instance it's called on.
No you can't call it exactly like that. You either need an instance of the class to call the non-static method, or it also needs to be static.
An alternative approach would be to use a singleton pattern - so you only have one instance of the class available throughout your code, and don't need to use static methods. That way, all methods in the class can call each other. It's hard to tell whether this would actually suit your needs, without further info but could be the way to go

Categories