I noticed in a custom base class that we use for a lot of our web pages we have a few static methods. Since the class is being used as a base class for web pages what benefit would it have making the methods static? I'm thinking none but wanted verification.
Also in custom base class we have properties that call other static methods in a manager class of ours in another class library and returns either a DataTable or HashTable.
I can see where as a convenience factor for devs to code against but other than that is their any reason for making the methods static in there as well?
So existing code looks something like this:
public class CustomBaseClass
protected Hashtable displayText
{
get{
if(_displayText == null)
displayText = MyManager.GetCustomersList(sCustID);
since GetCustomersList is static every method inside this method has to be static as well. All the way down to our data access layer. Just seems odd to me coding it this way but was curious as to what you all thought.
Our old developers who coded our application are gone and they use them all over the place. Is their any negatives or watch out fors to using static methods especially in an asp.net app?
If I create a singleton wouldn't that make more sense, then I wouldn't have to make all the method calls right down to our DAL static? lol
The main reason to make a method static typically is when it does not depend on any instance members of the class. The avoids having to create a new instance of the class to call the method, which then needs to be garbage collected later.
Both static and instance methods obviously have their place. Typically I create static methods for utility methods that get all their state from either static members (though you have to synchronize of course) or parameters, or to set a class-wide property for all instances of the class.
You can use a singleton (though some folks hate them), or you can just have your DAO objects created at the highest level class and injected further down, of course.
The main problem with using static methods, is that while it's very easy to unit test static methods, it can be more difficult to mock the results from calls to a static DAO class. It's much easier to mock if it's an injected instance.
The only reason to mark something static in the context of a web application (and this question) is so that it is shared across all request threads and stays in memory. That means that if two requests are both processing and each try to set the static piece of data, you have a race condition (and threading problems potentially).
In your particular case, it seems your old developers were just lazy; there is no reason why it must be static (based on the code sample provided).
A better option than a singleton or a static class would be to use the Monostate Pattern.
Basically, in the Monostate Pattern, you give your static class or singleton the semantics of an ordinary class, by marking all the static members private and providing a public instance wrapper. It's a way of hiding an implementation detail, so the class gets instantiated and used just as if individual instance were being allocated on the heap.
A Monostate brings two big benefits:
Consistent Semantics. Consumers use the monostate as they would any other class.
Implementation Hiding. With the implementation hidden — fact that the class is static or a singleton — if and when, down the line, the class implementation needs to change, the change is limited to just the source file implementing the class. Consumers of the class are unaware of the change.
Without the monostate, when the class implementation changes, every consumer of the class, every reference to the class or to the member being changed must be changed simultaneously, potentially a large number of source files scattered across many projects.
Here's a trivial example of a static class as a Monostate
public class MyMonostateClass
{
#region internal, static implementation
private static string dataItem;
private static int someMethod( int foo )
{
return 0 ; // do something useful return the appropriate value
}
#endregion internal, static implementation
#region public instance implementation wrappers
public string DataItem
{
get { return dataItem; }
set { dataItem = value; }
}
public int SomeMethod( int foo )
{
return MyMonostateClass.someMethod(foo);
}
#endregion public instance implementation wrappers
public MyMonostateClass()
{
return ;
}
}
and one of a Monostate singleton:
public class MyMonostateSingletonList : IList<int>
{
private static readonly IList<int> instance = new List<int>() ;
public MyMonostateSingletonList()
{
return ;
}
public int IndexOf( int item )
{
return instance.IndexOf(item) ;
}
public void Insert( int index , int item )
{
instance.Insert( index , item ) ;
}
public void RemoveAt( int index )
{
instance.RemoveAt( index ) ;
}
public int this[int index]
{
get
{
return instance[index] ;
}
set
{
instance[index] = value ;
}
}
public void Add( int item )
{
instance.Add(item) ;
}
public void Clear()
{
instance.Clear() ;
}
public bool Contains( int item )
{
return instance.Contains(item) ;
}
public void CopyTo( int[] array , int arrayIndex )
{
instance.CopyTo( array , arrayIndex ) ;
}
public int Count
{
get { return instance.Count ; }
}
public bool IsReadOnly
{
get { return instance.IsReadOnly ; }
}
public bool Remove( int item )
{
return instance.Remove(item);
}
public IEnumerator<int> GetEnumerator()
{
return instance.GetEnumerator() ;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return instance.GetEnumerator() ;
}
}
I would say there is no advantages or disadvantages but it depends on your requirement whether you should opt static methods or not. Think of below scenarios:
You should not use static class/members/methods: In general cases, for example - If you need to store and fetch user access information.
You should use static methods: If you need to implement some utility methods like sending email, logging error, getting value from web.config, getting ip address of client side.
Whenever you write a function or declare a variable, it doesn’t create instance in a memory until you create object of class. But if you declare any function or variable with static modifier, it directly create instance in a memory and acts globally. The static modifier doesn’t reference with any object.
I hope this helps..
Related
A Quick Note
The code in this post is built on top of a in-house built DirectX-11 engine which means it follows the strict pattern of:
Initialize
while (Running) {
Update
Render
}
However, do not let this deter you as the problem is not related to the DirectX code but instead static classes and methods.
Overview
I have a class called RenderObject which contains a method called Initialize. This method is responsible for building the object's mesh, assigning textures, shaders, and more.
public class RenderObject {
public virtual void Initialize() { }
}
I also have a few static classes that hold reusable assets such as common textures, shaders, models, and meshes. This way I don't have to reload them later. All of these static classes also contain a method called Initialize which is responsible for creating these reusable assets. For this question I will limit this to just the Textures class.
public static class Textures {
public static Texture2D Dirt { get; private set; }
public static Texture2D Grass { get; private set; }
public static void Initialize() {
Dirt = new Texture2D(...);
Grass = new Texture2D(...);
}
}
Finally, I have a class called LoadingSystem which is responsible for loading reusable assets and initializing objects. I initialize this class inside of the Initialize method of my engine, and then call the class' Update method in the Update method of the engine respectively. The LoadingSystem's Update method is responsible for loading and initializing objects using a Queue which is useful for supplying smooth visual feedback.
public class LoadingSystem {
public bool Loading { get; private set; } = true;
private Queue<RenderObject> objectsToRender;
public void AddForLoad(RenderObject obj) => objectsToRender.Enqueue(obj);
public void Update() {
if (objectsToRender.Count > 0) {
RenderObject obj = objectsToLoad.Dequeue();
obj.Initialize();
} else Loading = false;
}
}
The Problem
I would like to call the method Initialize on these static classes with the same process used for the RenderObject queue. Currently I'm forced to do:
CurrentMessage = "Loading Textures";
Render();
Present();
Textures.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
CurrentMessage = "Loading Shaders";
Render();
Present();
Shaders.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
CurrentMessage = "Loading Models";
Render();
Present();
Models.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
I've slimmed it down to a method that handles the repetitive setting of the message, and calls to Render and Present but this is still tedious and it should go through the Update method once per object to remain consistent with the rest of the code.
My Thoughts
I understand that a static class cannot inherit from a class or implement an interface so I am wondering if there is a way to provide a static class and call its Initialize method in a similar manner; even if this means creating a separate method to accomplish it.
I have currently considered two options:
Load static classes individually.
Convert static classes to instance classes and call them with the queue.
The problem with the first option is that I have 12 static classes and would have to update progress and feedback messages, raise events, and re-render the scene for each one.
The problem with the second option is that these static classes only contain static properties and thus by definition should be static as there is no need to ever inherit from them or create an instance of them.
The Question
Is there a way to call a common method across multiple static classes?
Perhaps a way to call the method if it exists with generic types like object or T?
Perhaps the dynamic type may work (though you can't create an instance of static classes)?
I have currently considered two options:
Load static classes individually.
Convert static classes to instance classes and call them with the queue.
A third compromise approach relates to your second idea above, but uses a design pattern known as the Singleton Pattern. Like static classes, there can only be one of them in your process and everyone gets that same thing, however unlike static classes, Singletons can implement interfaces or even descend from other classes.
For this example, I will use the interface approach.
public interface IInitializable
{
void Initialize();
}
All the interface does is to enforce that its implementer has an Initialize method.
My next step is to create a Singleton class. There are a couple of rules to implement the Singleton pattern. Your class must be sealed. Its constructor must be private. It must have a static method or property to return the single instance. That method/property must be threadsafe.
I have used Lazy to do the heavy lifting for me
public sealed class Foo : IInitializable
{
public void Initialize()
{
// Initialize my foo
}
private Foo()
{
}
private static Lazy<Foo> fooLazy = new Lazy<Foo>(() => new Foo());
public static Foo Instance => fooLazy.Value;
}
There are some minor differences to what you were doing with static classes. If Foo was a static class, you would call Foo.Initialize(); As it is Singleton, you would call Foo.Instance.Initialize();
Any other methods or properties would most likely be non-static.
Pulling it all together, you could write code like this. Your queue does not need to know about the classes it holds. You don't actually care. You only want to know that it has the Initialize() method
public class YourClass
{
private Queue<IInitializable> objectsToLoad = new Queue<IInitializable>();
public void Enqueue(IInitializable obj)
{
this.objectsToLoad.Enqueue(obj);
}
public void LoadOrUpdate()
{
// Update Method
if (objectsToLoad.Count > 0)
{
IInitializable obj = objectsToLoad.Dequeue();
obj.Initialize();
}
else
{
// Loading complete.
}
}
}
This class could then be used like this
YourClass yourClass = new YourClass();
yourClass.Enqueue(Foo.Instance);
yourClass.LoadOrUpdate();
Though I hope there is a much better and more detailed answer than this; I've come up with a basic solution. I created a separate Queue<Type> where I add the static classes. I then call their Initialize method with the following:
Type t = typesToInit.Dequeue();
t.GetMethod("Initialize").Invoke(null, new object[] { 0 });
This works well and is rather clean, but I can't help but wonder if there is a better way to do this?
Is there any use of declaring a static class as private.Here is the code below:
static class DerivedClass
{
private static string GetVal()
{
return "Hello";
}
}
The sample code you provided actually illustrates an internal class, not a private class. This is perfectly fine and is done all the time. It means the methods of the class are available from other classes within the same module, but not externally.
If you mean declaring private members of static classes, sure there is.
static class DerivedClass
{
public static string GetVal()
{
return GetValInternal();
}
private static string GetValInternal()
{
return "Hello";
}
}
If you mean declaring a private static nested classes (because only nested classes can be private, according to the documentation), then you can do it, but there's probably no reason to do it.
class SomeClass
{
private static class DerivedClass
{
public static string GetVal()
{
return "Hello";
}
}
}
Is equivalent to
class SomeClass
{
private static string GetVal()
{
return "Hello";
}
}
By default classes with no access modifiers like in your example are internal, not private. See this reference: http://msdn.microsoft.com/en-us/library/ms173121.aspx. This means that you can access this class from anywhere inside the library/project. This makes sense because it allows you to use the class internally without necessarily exposing it to the outside world.
Explicitly declaring it as private however makes sense in some rare cases only in my opinion. I have used it before for nested classes simply to group certain things together and make my code prettier/more readable. However I find that if I am creating nested classes it usually means that I need to redesign my code and pull some of it into separate files and separate classes. Rather try to stick to one class per file.
Here is a piece of code:
private class myClass
{
public static void Main()
{
}
}
'or'
private class myClass
{
public void method()
{
}
}
I know, first one will not work. And second one will.
But why first is not working? Is there any specific reason for it?
Actually looking for a solution in this perspective, thats why made it bold. Sorry
It would be meaningful in this scenario; you have a public class SomeClass, inside which you want to encapsulate some functionality that is only relevant to SomeClass. You could do this by declaring a private class (SomePrivateClass in my example) within SomeClass, as shown below.
public class SomeClass
{
private class SomePrivateClass
{
public void DoSomething()
{
}
}
// Only SomeClass has access to SomePrivateClass,
// and can access its public methods, properties etc
}
This holds true regardless of whether SomePrivateClass is static, or contains public static methods.
I would call this a nested class, and it is explored in another StackOverflow thread.
Richard Ev gave a use case of access inside a nested classes. Another use case for nested classes is private implementation of a public interface:
public class MySpecialCollection<T> : IEnumerable<T>
{
public IEnumerator<T> GetEnumerator()
{
return new MySpecialEnumerator(...);
}
private class MySpecialEnumerator : IEnumerator<T>
{
public bool MoveNext() { ... }
public T Current
{
get { return ...; }
}
// etc...
}
}
This allows one to provide a private (or protected or internal) implementation of a public interface or base class. The consumer need not know nor care about the concrete implementation. This can also be done without nested classes by having the MySpecialEnumerator class be internal, as you cannot have non-nested private classes.
The BCL uses non-public implementations extensively. For example, objects returned by LINQ operators are non-public classes that implement IEnumerable<T>.
This code is syntactically correct. But the big question is: is it useful, or at least usable in the context where you want to use it? Probably not, since the Main method must be in a public class.
Main() method is where application execution begin, so the reason you cannot compile your first class (with public static void Main()) is because you already have Main method somewhere else in your application. The compiler don't know where to begin execute your application.
Your application must have only one Main method to compile with default behavior otherwise you need to add /main option when you compile it.
I currently have a class which I instantiate when I start my program. The class itself will create a new thread and begin to search for broadcasts from routers.
I have other windows, other then MainWindow, which needs to be able to access the data stored within the instance of this class. However, I'm not sure as to how the other windows can reference this data.
Is there some other way I can store the instance of this class so that it is accessible application wide? I need it to start right when the rest of the application starts, so it seemed logical (to me) to have the class be instantiated in the first window.
namespace Lalu_WPF
{
public partial class MainWindow : Window
{
// data storage for program
public FindRouter finder = new FindRouter();
public MainWindow()
{
......
Don't make Singleton (notice the capital letter). It is error prone in multiple threads environments(muttable Singletons) and bad for testing.
What are your requirements?
Do you have to have one object in one application or one object in whole CLR?
I bet the first one.
Make an object in your App class (App.xaml.cs) and then acces it via getter
App MyApplication = ((App)Application.Current);
MyApplication.Router;
Don't use a Singleton, it makes unit testing hard and your code surprising.
Give classes which need access to an instance the instance. That means that every class which needs this single instance should accept either by a constructor argument or setter. Whoever creates the class is then in charge of supplying the dependency. This is called Dependency Injection.
You could make the class a singleton and this way you could access this same instance across the entire application. You can see an example on the msdn website here
Do you have a Program class? In the Windows Forms projects that I do, variables such as that go in Program public static readonly members or in public static properties with get only.
What you're talking about sounds like the Singleton design pattern. You could create a singleton object, a static class, or (what I like) a Monostate object (an object that encapsulates the static class or single instance) , something like this:
public class SingletonWidget
{
private static readonly Implementation SingleInstance ;
public void DoSomething( int someValue )
{
SingleInstance.DoSomething( someValue ) ;
return ;
}
public int SomeProperty
{
get
{
return SingleInstance.SomeProperty ;
}
set
{
SingleInstance.SomeProperty = value ;
}
}
static SingletonWidget()
{
SingleInstance = new Implementation() ;
return ;
}
private class Implementation
{
public void DoSomething( int someValue )
{
// ...
}
public int SomeProperty { get ; private set ; }
}
}
Usage looks like normal object instantation:
SingletonWidget foo = new SingletonWidget() ;
foo.DoSomething(3) ;
but under the covers, there's just a single instance hanging around. Changing from a static class or singleton is trivial as only the wrapper needs to change. Building stubs or mocks is pretty easy, too.
It makes it easy to
Try a DI framework or some less complex implementation of a service locator. That will allow you to provide the instance where it is needed throughout your app without hardcoding in a singleton, which is then painful to write tests around.
I know that Ninject at least provides support for single instances application-wide. I haven't used it in a WPF application but I can't see why not.
As a basic example of a service locator you could do something like the following. I've called the shared class Foo:
public interface IFoo { ... }
public class Foo { ... }
public class ServiceLocator
{
IFoo _foo = new Foo();
public IFoo GetFoo() { return _foo; }
}
public class DependsOnFoo
{
public IFoo Foo = ServiceLocator.GetFoo();
...
}
DependsOnFoo.Foo is the shared instance of Foo by default but when writing automated tests you could swap it out with a stub or mock:
var testTarget = new DependsOnFoo();
testTarget.Foo = mockFooImplementation;
// now testTarget isn't bound to the Foo implementation
As far as I understand your question is how to store a reference to your finder rather than how to create it. If this is the case I would suggest using IDictionary Application.Current.Properties property, which is nothing but a collection of application-scope properties. At startup you can create your object and store a reference to it like this:
Application.Current.Properties["finder"] = new FindRouter();
Then, in any place of your program you can access it like
FindRouter finder = (FindRouter)Application.Current.Properties["finder"];
Hope this helps.
Is there anyway of having a base class use a derived class's static variable in C#? Something like this:
class Program
{
static void Main(string[] args)
{
int Result = DerivedClass.DoubleNumber();
Console.WriteLine(Result.ToString()); // Returns 0
}
}
class BaseClass
{
public static int MyNumber;
public static int DoubleNumber()
{
return (MyNumber*2);
}
}
class DerivedClass : BaseClass
{
public new static int MyNumber = 5;
}
I'm trying to have it return 10, but I'm getting 0.
Here's where I'm using this: I have a class called ProfilePictures with a static function called GetTempSavePath, which takes a user id as an argument and returns a physical path to the temp file. The path base is a static variable called TempPath. Since I'm using this class in multiple projects and they have different TempPaths, I'm creating a derived class that sets that variable to whatever the path is for the project.
See Also
Why can’t I declare C# methods virtual and static?
Apart from the fact that has already been pointed out... that static variables are tied or bound to the specific class declaring them and cannot be overridden. Overriding/Polymorphism needs instances to work.
Your problem can be solved with a change in design.
string ProfilePictures.GetTempSavePath(SomeType UserId, string sBasePath)
if it just needs these 2 variables to compute the return value, you can keep it as a utility/static method. Now you can feed in different base paths..
Now it seems from your question, that you need to use this class in multiple projects (which have fixed base paths) and kind of hardcode the base path so that you dont have to specify it for each call.
Type/Class hierarchies should be defined based on behavior and not on data. Variables can handle change in data. Hence I'd suggest holding the basepath value as a static member variable, which is initialized from a resource file (DoubleClick your project properties node > Settings > Add a new Settings file > add a new setting called BasePath - string - Application scope - VALUE=C:\Users). Now you just need to tweak the app.config file for each project, no code changes, no hardcoding and not more than one type needed.
public class PathHelper
{
static string _sBasePath;
static PathHelper()
{
_sBasePath = Properties.Settings.Default.BasePath;
}
static string GetTempSavePath(string sUserId)
{
// dummy logic to compute return value, replace to taste
return Path.Combine(_sBasePath, sUserId.Substring(0, 4));
}
}
Hope that made sense
The problem is that you're re-declaring the static variable in the derived class. The MyNumber declaration in DerivedClass hides the declaration in the base class. If you remove that declaration, then references to the "MyNumber" in derived class static functions will refer to the base class variable. Of course, if you remove the declaration then you can't use a static initializer in the derived class.
You might want to consider requiring users to instantiate an instance of ProfilePictures rather than provide a static function for GetTempSavePath. That way you could overide the GetTempSavePath method to provide the correct TempPath. Or, you could simply set the value of the static path value in your derived class constructor.
Although it is possible to use inheritance with static members, you can't relly have polymorphic behavior without a "this" pointer.
Static members are not virtual, so you can not override them.
When you call DerivedClass.DoubleNumber you are actually calling BaseClass.DoubleNumber as the DerivedClass class doesn't have that method. Also, the use of MyNumber in that method is always going to be BaseClass.MyNumber no matter how you call the method.
What you are looking for is a virtual property that you can override in a derived class. As a virtual member can not be static, you need to use an instance of the class. If it's not practical to keep a reference to the instance, you can use the singleton pattern.
This kinda works:
public class ClassA
{
protected static int num = 5;
public static int GetNum()
{
return num;
}
}
public class ClassB : ClassA
{
static ClassB()
{
num = 6;
}
}
However, note the difference when you call ClassB.GetNum() before and after instantiating one object. The static initializer doesn't run until you create at least one, so you'll get 5 if nothing has been created, and 6 if at least one object has.
Provide a virtual method that returns the class static.
class BaseClass
{
public virtual int GetMyNumber() { return MyNumber; }
}
You might want to use a virtual property instead...
Using too much of static members is also not recommended if they are going to encapsulate a logic of an entire object. For example your code can be rewritten correctly in following manner... and this is the most recommended in oops,
class Program
{
static void Main(string[] args)
{
int Result = DerivedClass.Instance.DoubleNumber();
Console.WriteLine(Result.ToString()); // Returns 0
}
}
class BaseClass
{
protected BaseClass(){} // this enforces that it can not be created
public int MyNumber;
public virtual int DoubleNumber()
{
return (MyNumber*2);
}
}
public class DerivedClass : BaseClass
{
// this also ensures that it can not be created outside
protected DerivedClass(){
MyNumber = 5;
}
// only way to access this is by Instance member...
public static DerivedClass Instance = new DerivedClass();
}
This is how we access configuration values and many other single instance static objects provided by .Net Library.