What's the difference between static classes, and static methods? I want to learn the differences, and when I might use one vs. the other.
For example, I have a class like this:
static class ABC
{
public int a;
public void function_a()
{
a = 10;
}
}
and another class like this:
class DEF
{
public static int a;
public static void function_a()
{
a= 10;
}
}
I have used the second type of class many times, and I know the usage. What's the usage of the first example?
Your first example will not compile, a static class must have all static members.
The difference between just using some static methods and a static class is that you are telling the compiler that the class cannot be instantiated. The second example you can create an object of the DEF class even though there are no instance methods in it. The ABC class cannot be instantiated with the new operator (will get a compile-time error).
When to Use Static Classes
Suppose you have a class CompanyInfo that contains the following methods to get information about the company name and address.
C#
class CompanyInfo
{
public string GetCompanyName() { return "CompanyName"; }
public string GetCompanyAddress() { return "CompanyAddress"; }
//...
}
These methods do not need to be attached to a specific instance of the class. Therefore, instead of creating unnecessary instances of this class, you can declare it as a static class, like this:
C#
static class CompanyInfo
{
public static string GetCompanyName() { return "CompanyName"; }
public static string GetCompanyAddress() { return "CompanyAddress"; }
//...
}
Use a static class as a unit of organization for methods not associated with particular objects. Also, a static class can make your implementation simpler and faster because you do not have to create an object in order to call its methods. It is useful to organize the methods inside the class in a meaningful way, such as the methods of the Math class in the System namespace.
Related
This question already has answers here:
Why do members of a static class need to be declared as static? Why isn't it just implicit?
(8 answers)
Closed 8 years ago.
All members must be explicitly specified as static, static class does not automatically make its members static. Static class can contain a collection of static methods.
The definition explains all i.e we need to explicitly give static for methods , members etc inside static class .
What i really didn't get here is if there is a rule like we can declare only static members inside a static class
why doesn't the developer of OOPL make it not mandate . so the compiler should understand(internally) i.e even if we declare a non-static method inside a static class it should understand the method as static (i.e static class can only have static methods) .
I got this doubt when i am working on interfaces see even in case of interfaces all interfaces members are public so we don't declare then public explicitly compiler will understand internally .
All i am looking is for a big WHY not for excuses(it should be like that , its in-build functionality).
I imagine because a) it is easier to see and b) is consistent:
Easier to see
public static class WithoutStaticMembers
{
public string GetString() // easy to miss that it is static
{
return "string";
}
}
public static class WithStaticMembers
{
public static string GetString() // clearly static
{
return "string";
}
}
Consistant
public class NotStaticClass
{
public static string GetString()
{
return "string";
}
}
public static class StaticClass
{
public static string GetString()
{
return "string";
}
}
// ...
var s1 = NotStaticClass.GetString();
var s2 = StaticClass.GetString(); // consistent across both static class and not static
Inside of a public class:
public static class LogReporting
I have the following method:
public void RunTimerJobs()
{
SPAdministrationWebApplication centralAdmin = SPAdministrationWebApplication.Local;
try
{
foreach (SPService service in centralAdmin.Farm.Services)
{
Guid traceGuid = new Guid("d3beda82-38f4-4bc7-874f-ad45cebc9b35");
Guid eventGuid = new Guid("3ea057b3-0391-4c33-ac8d-412aecdda97d");
var traceJob =
from jobDefinition in service.JobDefinitions
where jobDefinition.Id == traceGuid
select jobDefinition;
if (traceJob != null && traceJob.Count() == 1)
{
traceJob.First().RunNow();
}
var eventJob =
from jobDefinition in service.JobDefinitions
where jobDefinition.Id == eventGuid
select jobDefinition;
if (eventJob != null && eventJob.Count() == 1)
{
eventJob.First().RunNow();
}
}
}
catch (Exception ex)
{
//Loggers.SharePointLogger logger = new Loggers.SharePointLogger();
//logger.WriteTrace(ex.Message, LogProduct.MonitoringView, LogTraceSeverity.Unexpected);
}
However it will not allow me to compile citing that RunTimerJobs() "cannot declare instance members in a static class"
To my knowledge, none of the 'instance members' I declare are able to be labeled as static, so is there just a fundamental issue with the setup (i.e. a static class) or am I missing some little snippet?
Your class is static thus you cannot have any instance members because you will never instantiate the class.
To be able to use the RunTimerJobs() method you would need to create an instance of the LogReporting class, i.e.
LogReporting logReporting = new LogReporting();
logReporting.RunTimerJobs();
This obviously won't work though because your class is defined as static and you cannot create instances of it.
Either make your method static or remove the static keyword from your class declaration - depending on what you require.
I see no instance related logic in your method so it should be safe to mark it as static.
Remember
Classes can have a mixture of instance and static members as long as the class isn't marked static.
And
Only mark classes as static when you know that ALL members (properties, methods etc...) will be static as well.
The compiler's being pretty clear here. You're declaring a static class, and static classes can only contain static members. So this is okay:
public class NonStaticClass
{
public void InstanceMethod() {}
}
And this is okay:
public static class StaticClass
{
public static void StaticMethod() {}
}
But this isn't:
public static class StaticClass
{
public void InstanceMethod() {}
}
If you wanted to declare instance members, why did you declare LogReporting as a static class?
When class marked as static, then all it's members should be static (instances creation is not allowed). You can read more about static classes on msdn.
So, if you want to have instance (non-static) method, then remove static keyword from class definition:
public class LogReporting
{
public void RunTimerJobs()
{
//...
}
}
In this case you should create LogReporting instance to call your method:
LogReporting log = new LogReporting();
log.RunTimerJobs();
Another option for you - making your method static:
public static class LogReporting
{
public static void RunTimerJobs()
{
//...
}
}
In this case you don't need instance of LogReporting:
LogReporting.RunTimerJobs();
Did you try:
public static void RunTimerJobs()
For a static class, the members must also be static. If you are unable make the members static, then you must make the class non-static as well.
It's generally a good idea to use non-static classes if you can, as static classes increase the complexity of unit testing as they cannot be mocked out easily. Of course if you have a legitimate need to use a static class, then by all means do so.
I have read through the follow SO articles
C#: How do I call a static method of a base class from a static method of a derived class?
Can I have a base class where each derived class has its own copy of a static property?
What's the correct alternative to static method inheritance?
All seem very close to my question and have good answers, but they do not seem to answer my question other than to say that I need to make the method non-static.
an example:
abstract public class baseClass
{
private static List<string> attributeNames = new List(new string {"property1","property2"});
// code for property definition and access
virtual public static bool ValidAttribtue(string attributeName)
{
if (attributeNames.Contains(attributeName))
return true;
else
return false;
}
}
class derivedA : baseClass
{
private static List<string> attributeNames = new List(new string {"property3","property4"});
// code for property definition and access
public static override bool ValidAttribute(string attributeName)
{
if (attributeNames.Contains(attributeName))
{
return true;
}
else
{
return base.ValidAttribute(attributeName);
}
}
}
class derivedB : baseClass
{
private static List<string> attributeNames = new List(new string {"property10","property11"});
// code for property definition and access
public static override bool ValidAttribute(string attributeName)
{
if (attributeNames.Contains(attributeName))
{
return true;
}
else
{
return base.ValidAttribute(attributeName);
}
}
}
derivedA would have properties 1,2,3,4 while derivedB would have properties 1,2,10,11.
The list of properties seems to be a class specific value and can not be changed at any point. I would think it then would be static.
Is my design wrong in the sense that I am trying to use static methods when they should not be?
The above example makes me think that inheritance of static methods would be needed, yet it seems that trying to do this is a design flaw. Can anyone help me to understand what is wrong with coding or structuring classes in this manner?
Is my design wrong in the sense that I am trying to use static methods when they should not be?
Yes. Aside from anything else, you're trying to declare a static method as virtual (and then override it), which isn't allowed. You're also trying to declare a class called base, when that's a keyword.
Static methods simply aren't polymorphic. The basis of polymorphism is that the execution time type of the instance involved can be different to the compile-time type of the expression, and the implementation is chosen on the basis of the execution time type. That concept doesn't make sense for static methods as there is no instance.
Now of course you can make a static method in a derived class call a static method in the base class - but there won't be any polymorphism anywhere.
As a side note, all of your methods could be written in a more readable way:
// Base class implementation
return attributeNames.Contains(attributeName);
// Derived class implementations
return attributeNames.Contains(attributeName) ||
BaseClass.ValidAttribute(attributeName);
I want to inherit to extend the C# string class to add methods like WordCount() and several many others but I keep getting this error:
Error 1 'WindowsFormsApplication2.myString': cannot derive from sealed
type 'string'
Is there any other way I can get past this ? I tried with string and String but it didn't work.
Another option could be to use an implicit operator.
Example:
class Foo {
readonly string _value;
public Foo(string value) {
this._value = value;
}
public static implicit operator string(Foo d) {
return d._value;
}
public static implicit operator Foo(string d) {
return new Foo(d);
}
}
The Foo class acts like a string.
class Example {
public void Test() {
Foo test = "test";
Do(test);
}
public void Do(string something) { }
}
System.String is sealed, so, no, you can't do that.
You can create extension methods. For instance,
public static class MyStringExtensions
{
public static int WordCount(this string inputString) { ... }
}
use:
string someString = "Two Words";
int numberOfWords = someString.WordCount();
If your intention behind inheriting from the string class is to simply create an alias to the string class, so your code is more self describing, then you can't inherit from string. Instead, use something like this:
using DictKey = System.String;
using DictValue= System.String;
using MetaData = System.String;
using SecurityString = System.String;
This means that your code is now more self describing, and the intention is clearer, e.g.:
Tuple<DictKey, DictValue, MetaData, SecurityString> moreDescriptive;
In my opinion, this code shows more intention compared to the same code, without aliases:
Tuple<string, string, string, string> lessDescriptive;
This method of aliasing for more self describing code is also applicable to dictionaries, hash sets, etc.
Of course, if your intention is to add functionality to the string class, then your best bet is to use extension methods.
You cannot derive from string, but you can add extensions like:
public static class StringExtensions
{
public static int WordCount(this string str)
{
}
}
What's wrong with a helper class? As your error message tells you, String is sealed, so your current approach will not work. Extension methods are your friend:
myString.WordCount();
static class StringEx
{
public static int WordCount(this string s)
{
//implementation.
}
}
You can't inherit a sealed class (that's the whole point of it) and the reason why it wouldn't work with both string and System.String is that the keyword string is simply an alias for System.String.
If you don't need to access the internals of the string class, what you can do is create an Extension Method, in your case :
//note that extension methods can only be declared in a static class
static public class StringExtension {
static public int WordCount(this string other){
//count the word here
return YOUR_WORD_COUNT;
}
}
You still won't have access to the private methods and properties of the string class but IMO it's better than writing :
StringHelper.WordCount(yourString);
That's also how LINQ works.
The string class is marked sealed because you are not supposed to inherit from it.
What you can do is implement those functions elsewhere. Either as plain static methods on some other class, or as extension methods, allowing them to look like string members.
Could anyone tell me is there any other way a method can be overridden without using virtual/abstract/override in C#/.NET, Please provide me with an example.Please provide with an example...
(what i am thinking is Extension methods am i correct.....)
No, there is no other way. You can hide an existing method with new if the base method is not marked as virtual, however it does not have the same effect (there is no polymorphism - the call will be dispatched based on the variable type, not on the actual object type).
Extension will not work in this case. Objects own properties and methods take precedence. However you can overload a method using extensions.
You can override methods defined in the extensions, by keeping your extensions closer in the namespace to the place where you are going to use it.
Example:
namespace ConsoleApplication2
{
using System;
using ConsoleApplication3;
internal class Program
{
private static void Main(string[] args)
{
ThirdPartyClass t = new ThirdPartyClass();
Console.WriteLine(t.Fun("hh"));
Console.WriteLine(t.Fun(1));
}
}
public static class LocalExtension
{
public static string Fun(this ThirdPartyClass test, int val)
{
return "Local" + val;
}
public static string Fun(this ThirdPartyClass test, string val)
{
return "Local" + val;
}
}
}
namespace ConsoleApplication3
{
public class ThirdPartyClass
{
public virtual string Fun(string val)
{
return "ThirdParty" + val.ToUpper();
}
}
public static class ThripartyExtension
{
public static string Fun(this ThirdPartyClass test, int val)
{
return "ThirdParty" + val;
}
}
}
You can use the "new" keyword on your method to "hide" a method that was not declared as abstract/virtual, however if the method is called from a variable type-casted as the base class, it won't call your new method. This is the similar to overriding.
Example:
public class A
{
public string GetName() { return "A"; }
}
public class B : A
{
// this method overrides the original
public new string GetName() { return "B"; }
}
Extension methods allow you to add new methods to any class even if you don't have their source code or they're sealed. This is not the same as overriding
public sealed class A // this could even be from a dll that you don't have source code to
{
}
public static class AExtensionMethods
{
// when AdditionalMethod gets called, it's as if it's from inside the class, and it
// has a reference to the object it was called from. However, you can't access
// private/protected fields.
public static string AdditionalMethod(this A instance)
{
return "asdf";
}
}
Another option is to use interfaces so that you can have two completely different objects that both have the same method, but when called from a variable type-casted as the interface, it looks similar to overriding.
You could also use a form of Proxy Mocking framework like Microsoft Moles, or CastleWindsor -> They have a way of instantiating a "proxy" object that has the same interface as the real object, but can provide a different implementation for each method.