I am working on a .NET based application, where some of the core application classes were designed with only static methods.
Example usage:
// static access.
Parameters.GetValue("DefaultTimeout");
// static access.
Logger.Log("This is an important message!");
There's already code out there that uses these static methods, so this "interface" cannot be changed.
These classes currently implement no interface. I would like to be able to separate the actual implementation of these classes from their interface.
The reason for this refactoring is that these objects will be used across AppDomain boundaries. I would like to be able to inject a "proxy" object that on non main-appdomains will invoke some other implementation instead of the default one.
To sum up, my questions are:
How can i easily transform objects with static-only access to an interface based design, such that their implementation may be replaced when needed (but keeping static access).
Once refactored, how/WHEN is the actual injection of the non-default implementation should occur?
Disclaimer: The following suggestion is based on the importance of not changing the calling side. I'm not saying it's the best option, just that I think it's suitable.
Disconnecting the Implementation
There is no way to have interfaces on static members, so if you don't want to change the calling code, the static will likely have to remain. That said, you can simply have your static class wrap an interface inside, so the static class itself doesn't have any implementation - it delegates all calls to the interface.
This all means you can leave your static class and any code that calls it in place. This will be like treating the static class as the interface (or contract), but having it internally swap out implementations based on the situation.
It also means your interface can have a different signature to the static class, as the interface doesn't have to conform to the calling code expectations - basically, it will turn your static class into a sort of Bridge.
Injecting the Implementation
In short: use a static constructor in order to resolve the given implementation of this interface.
Statics are per AppDomain normally (unless decorated with ThreadStaticAttribute, then per AppDomain/thread) so you can determine where you are and what implementation you need based on the current AppDomain (the static constructor will be called whenever the static is first used in the AppDomain). This means that once constructed, that particular static class's wrapped implementation will remain for the duration of the AppDomain (though you could implement methods to flush the implementation).
Cross AppDomain Calling
The code responsible for this can either be in the static classes or you can make one of the interface implementations simply a proxy manager to an AppDomain type. Any type for cross AppDomain calls will need to inherit MarshalByRefObject.
http://msdn.microsoft.com/en-us/library/ms173139.aspx
CreateInstance of a Type in another AppDomain
Simplest way to make cross-appdomain call?
Sample Application
You should just be able to copy and paste this into a new Console application. What this is doing is registering an implementation for the default AppDomain and one for the user-made AppDomains. The default simply creates a remote implementation of the interface (in the other AppDomain). Just to demonstrate the "static per AppDomain" idea, the remote implementation delegate to yet another implementation for non-default domains.
You can change implementations on the fly, all you need to change is the static class constructor (to decide what implementation to pick). Notice that you do not need to change the Main method, our calling code in this case.
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
Console.WriteLine(Parameters.GetValue(""));
Console.Read();
}
}
static class Parameters
{
private static IParameterProvider _provider;
static Parameters()
{
if (AppDomain.CurrentDomain.IsDefaultAppDomain())
{
_provider = new ParameterProviderProxy(AppDomain.CreateDomain(Guid.NewGuid().ToString()));
}
else
{
// Breakpoint here to see the non-default AppDomain pick an implementation.
_provider = new NonDefaultParameterProvider();
}
}
public static object GetValue(string name)
{
return _provider.GetValue(name);
}
}
interface IParameterProvider
{
object GetValue(string name);
}
class CrossDomainParameterProvider : MarshalByRefObject, IParameterProvider
{
public object GetValue(string name)
{
return Parameters.GetValue(name);
}
}
class NonDefaultParameterProvider : IParameterProvider
{
public object GetValue(string name)
{
return AppDomain.CurrentDomain.FriendlyName;
}
}
class ParameterProviderProxy : IParameterProvider
{
private IParameterProvider _remoteProvider;
public ParameterProviderProxy(AppDomain containingDomain)
{
_remoteProvider = (CrossDomainParameterProvider)containingDomain.CreateInstanceAndUnwrap(
Assembly.GetExecutingAssembly().FullName,
typeof(CrossDomainParameterProvider).FullName);
}
public object GetValue(string name)
{
return _remoteProvider.GetValue(name);
}
}
A Note on Life Span
One of the main problems with managing a refactoring of static classes isn't usually the changing of the client code (as this is supported by lots of refactoring tools and there are techniques to get it done safely), but managing the life span of the object. Instance objects rely on living references (otherwise they are garbage collected), these can usually be made "easily accessible" by keeping one in a public static member somewhere, but usually this is what you are trying to avoid by refactoring in the first place.
It doesn't seem like you will have to worry about this concern, as you are leaving the calling code attached to the static classes, therefore the life span will remain the same.
For every static method, create an instance one. Add a static singleton variable that you can assign any implementation to. Make the static methods call the instance methods on the static singleton.
This will allow you to swap the implementation at runtime, but you can only have one implementation hooked in at the same time.
Existing code does not need to change.
Static Classes can be transformed into Singleton Objects.
Singleton Objects support interfaces.
Interfaces can be used for different implementations.
(1) Definition of Problem.
Suppose you have a class that have static members.
--
StringsClass.cs
--
namespace Libraries
{
public static class StringsClass
{
public static string UppercaseCopy(string Value)
{
string Result = "";
// code where "Value" is converted to uppercase,
// and output stored in "Result"
return Result;
} // string UppercaseCopy(...)
public static string LowercaseCopy(string Value)
{
string Result = "";
// code where "Value" is converted to lowercase,
// and output stored in "Result"
return Result;
} // string LowercaseCopy(...)
public static string ReverseCopy(string Value)
{
string Result = "";
// code where "Value" is reversed,
// and output stored in "Result"
return Result;
} // string ReverseCopy(...)
} // class StringsClass
} // namespace Libraries
--
And, several code that uses that static elements, from that class.
--
StringsLibraryUser.cs
--
using Libraries;
namespace MyApp
{
public class AnyClass
{
public void AnyMethod()
{
string Example = "HELLO EARTH";
string AnotherExample = StringsClass.LowercaseCopy(Example);
} // void AnyMethod(...)
} // class AnyClass
} // namespace MyApp
--
(2) Transform, first, the class, into a non static class.
--
StringsClass.cs
--
namespace Libraries
{
public class StringsClass
{
public string UppercaseCopy(string Value)
{
string Result = "";
// code where "Value" is converted to uppercase,
// and output stored in "Result"
return Result;
} // string UppercaseCopy(...)
public string LowercaseCopy(string Value)
{
string Result = "";
// code where "Value" is converted to lowercase,
// and output stored in "Result"
return Result;
} // string LowercaseCopy(...)
public string ReverseCopy(string Value)
{
string Result = "";
// code where "Value" is reversed,
// and output stored in "Result"
return Result;
} // string ReverseCopy(...)
} // class StringsClass
} // namespace Libraries
--
(3) Add code the allow class handle a single object.
--
StringsClass.cs
--
namespace Libraries
{
public class StringsClass
{
private static Singleton instance = null;
private Singleton()
{
// ...
}
public static synchronized Singleton getInstance()
{
if (instance == null) {
instance = new Singleton();
}
return instance;
}
public string UppercaseCopy(string Value)
{
string Result = "";
// code where "Value" is converted to uppercase,
// and output stored in "Result"
return Result;
} // string UppercaseCopy(...)
public string LowercaseCopy(string Value)
{
string Result = "";
// code where "Value" is converted to lowercase,
// and output stored in "Result"
return Result;
} // string LowercaseCopy(...)
public string ReverseCopy(string Value)
{
string Result = "";
// code where "Value" is reversed,
// and output stored in "Result"
return Result;
} // string ReverseCopy(...)
} // class StringsClass
} // namespace Libraries
--
(4) Code that calls the class, should add the reference for the singleton.
--
StringsLibraryUser.cs
--
using Libraries;
namespace MyApp
{
public class AnyClass
{
public void AnyMethod()
{
string Example = "HELLO EARTH";
string AnotherExample = StringsClass.getInstance().LowercaseCopy(Example);
} // void AnyMethod(...)
} // class AnyClass
} // namespace MyApp
--
(5) Define an interface, with similar declarations to the previous static class,
and allow the singleton, to implement that interface. Omit the singletons members, in the interface declaration
--
StringsClass.cs
--
namespace Libraries
{
public interface StringsInterface
{
string UppercaseCopy(string Value);
string LowercaseCopy(string Value);
string ReverseCopy(string Value);
} // interface StringsInterface
public class StringsClass: StringsInterface
{
private static Singleton instance = null;
private Singleton()
{
// ...
}
public static synchronized Singleton getInstance()
{
if (instance == null) {
instance = new Singleton();
}
return instance;
}
public string UppercaseCopy(string Value)
{
string Result = "";
// code where "Value" is converted to uppercase,
// and output stored in "Result"
return Result;
} // string UppercaseCopy(...)
public string LowercaseCopy(string Value)
{
string Result = "";
// code where "Value" is converted to lowercase,
// and output stored in "Result"
return Result;
} // string LowercaseCopy(...)
public string ReverseCopy(string Value)
{
string Result = "";
// code where "Value" is reversed,
// and output stored in "Result"
return Result;
} // string ReverseCopy(...)
} // class StringsClass
} // namespace Libraries
--
(6) In the code, where your are using your singleton, the previous class that contained static methods, replace the singleton for an interface.
--
StringsLibraryUser.cs
--
using Libraries;
namespace MyApp
{
public class AnyClass
{
public StringsInterface StringsHelper = StringsClass.getInstance().LowercaseCopy(Example);
public void AnyMethod()
{
string Example = "HELLO EARTH";
string AnotherExample = StringsHelper;
} // void AnyMethod(...)
} // class AnyClass
} // namespace MyApp
--
Now, you can add other classes that support the same declarations,
with different implementation.
Cheers.
--
Related
My goal is to have methods init() and complete(result) which will run before and after every method of a chosen class.
Similar to how the ActionFilterAttribute in ASP.NET has OnActionExecuting and OnActionExecuted methods that run before and after whatever method you apply them to.
There are multiple interfaces I would like to apply the same init() and complete(result) methods to, and I want to avoid code duplication and keep code easy to understand if possible.
From what I can tell, there doesn't seem to be an elegant solution. So far, I have 3 options:
Option 1:
public interface MyImportantMethods
{
object f();
object g();
}
public class MyClass : MyImportantMethods
{
public object f()
{
// Do things
}
public object g()
{
// Do things
}
}
public class WrappedMyClass : MyImportantMethods
{
private MyImportantMethods ActualContent;
public MyModifiedClass(MyImportantMethods actualContent)
{
this.ActualContent = actualContent;
}
public object f()
{
init();
object result = this.ActualContent.f();
complete(result);
return result;
}
public object g()
{
init();
object result = this.ActualContent.g();
complete(result);
return result;
}
}
Pros: The class with the implementation is completely separate from
the one which calls init() and complete(), so it is more readable and
simpler to understand.
Cons: It is easy for someone not familiar with the code to use the
wrong one. Requires a different class for each interface I want to
apply it to.
Option 2:
public interface MyImportantMethods
{
object f();
object g();
}
class Wrapper: IDisposable
{
public object result;
public Wrapper()
{
init();
}
void Dispose()
{
complete(result);
}
}
public class MyModifiedClass {
private void f()
{
using (var wrapper = new Wrapper(() => completeF()))
{
// Do Things
wrapper.result = result;
}
}
private void g()
{
using (var wrapper = new Wrapper(() => completeG()))
{
// Do Things
wrapper.result = result;
}
}
}
Pros: Not possible to use the wrong class. May be possible to use one
IDisposable class for all interfaces, if I use a reflection trick
Cons: Code will look much more cluttered and hard to understand for a
new reader, especially if the declaration of wrapper takes multiple
lines or wrapper needs more than one parameter from the result (both
are true in my case). Also relies on the caller to set the result.
Option 3:
public abstract class MyImportantMethodsBase
{
public object f()
{
init();
object result = this.fImplementation();
complete(fResult);
return result;
}
public object g()
{
init();
object result = this.gImplementation();
complete(result);
return result;
}
private abstract object fImplementation();
private abstract object gImplementation();
}
public class MyModifiedClass : MyImportantMethodsBase {
private object void fImplementation()
{
// Do Things
}
private object gImplementation()
{
// Do Things
}
}
Pros: Not possible to use the wrong class. The class with the
implementation is completely separate from the one which calls init()
and complete(), so it is more readable and simpler to understand.
Cons: Less simple for a reader to understand.
Is there really no way as simple and understandable as the ActionFilterAttribute to accomplish my goal?
Perhaps Option 1 with Factory Pattern is enough: Make constructor private so it can't be used the wrong way. Make a static function in the same class to construct the subject object and then create a wrapper object around it, returning that of a type that is the common shared interface.
However, If you have many classes to wrap, runtime code generation (or design time .tt code generation) could help you out. calling WrapperGenerator.Create(newObject) where T is the Interface and newObject is the private constructed object which implements that interface. The Create function reflects on the Interface, then you create a new class on the fly based on that interface which will wrap with the extra function calls around the functions found one the base object. Any newly created wrapper classes would be cached for the same Interface.
class WrapperGenerator
{
static Dictionary<Type,ConstructorInfo> cachedWrappers = new ...();
public static T Create<T>(object wrappedObject)
{
ConstructorInfo wrapperConstructor = null;
var found = cachedWrappers.TryGet(typeof(T), out wrapperConstructor);
if (found)
{
return (T)wrapperConstructor.Invoke(wrappedObject);
}
//cachedWrapper not found
wrapperConstructor = GenerateNewConstructor(typeof(T));
cachedWrappers.Add(typeof(T), wrapperConstructor);
return (T)wrapperConstructor.Invoke(wrappedObject);
}
static long Counter = 0;
static ConstructorInfo GenerateNewConstructor(Type t)
{
var methodList = t.GetMethods(...);
StringBuilder sb = new StringBuilder();
sb.Append("namespace WrapperClasses {\r\n");
var ClassName = "Wrapper" + Counter++;
var InterfaceName = t.FullName;
sb.AppendFormat("public class {0} {{\r\n", ClassName);
sb.AppendFormat("{0} wrappedObject = null;\r\n", ClassName);
sb.AppendFormat("public Wrapper{0}({1} wrappedObject) {"\r\n, ClassName, InterfaceName);
sb.Append(" this.wrappedObject = wrappedObject;\r\n");
sb.Append("}\r\n");
foreach (var m in methodList)
{
sb.AppendFormat("public {0} {1}({2}) {{", m.ReturnType.., m.Name, ParameterDeclarationsSegment(m));
sb.AppendFormat(" init();\r\n");
sb.AppendFormat(" var result = wrappedObject.{0}({1});\r\n", m.Name, ParameterPassthroughSegment(m));
sb.AppendFormat(" complete(result);\r\n");
sb.Append("};\r\n");
}
//ETC.. closing class and namespace
var LoadedAssembly = Compiler.Compile(sb,...);
var getWrapperType = LoadedAssembly.SearchType(ClassName);
return getWrapperType.GetConstructors()[0];
}
}
Note: You should implement locking around the cachedWrappers.
This seems like an odd request, I appreciate that, but this is the situation:
I have a program which depends on reading in a handful of files. These files are named like: foo_bar_BAZ.txt where BAZ is the name of the project and not known until run-time. However it will not change for the entire execution of the program.
I want to have an enumerated list of strings which stores all the filenames. So far I have used a sealed class like so:
public sealed class SQLFile
{
private readonly String name;
private readonly String value;
public static readonly SQLFile CrByAuthors = new SQLFile("Changes_CR_By_Authors_%project_name%.txt", "CrByAuthors");
public static readonly SQLFile DocumentCrMetrics = new SQLFile("Changes_Document_CR_Output_%project_name%.txt", "DocumentCrMetrics");
[...]
private SQLFile(String value, String name)
{
this.name = name;
this.value = value;
}
public String ToString(string projectName)
{
return this.value.Replace("%project_name%", projectName);
}
}
As you can see this depends on my providing the project name variable every time I want to access the filename, even though that filename is really constant from the very beginning of run-time till the end.
Is there a more elegant way to handle with this situation?
A simple solution would be to have a static class with a ProjectName property. The value of this property is set during startup of the application. Your class then can use that property.
Add a static property to SQLFile, something like
public sealed class SQLFile
{
//...
private static string sProjectName;
public static string ProjectName
{
get
{
return sProjectName;
}
set
{
//optionally, you could prevent updates with:
//if (string.IsNullOrEmpty(sProjectName))
sProjectName= value;
//else throw Exception("ProjectName was already set!");
}
}
[Edit - I read the code a bit too fast, so this is what I actually meant:]
The purpose of the (poorly named IMHO) method ToString is to return the name of a file corresponding to a certain project name. There is nothing wrong with that, although it may be a responsibility which might belong to a separated class.
You could, for example, refactor the code to express its intention more clearly:
interface ISqlFileNameProvider
{
string SqlFilename { get; }
}
Then have a simple ("poor man's") implementation:
public class SimpleSqlFileNameProvider : ISqlFileNameProvider
{
private readonly string _filename;
public SimpleSqlFileNameProvider(string filename)
{
_filename = filename;
}
public string SqlFilename
{
get { return _filename; }
}
}
And then derive specialized implementation from here:
public class TemplateSqlFileNameProvider : SimpleSqlFileNameProvider
{
public TemplateSqlFileNameProvider(string template, string projectName)
: base(template.Replace("%project_name%", projectName))
{ }
}
public class CrByAuthorsFileNameProvider : TemplateSqlFileNameProvider
{
public CrByAuthorsFileNameProvider(string projectName)
: base("Changes_CR_By_Authors_%project_name%.txt", projectName)
{ }
}
public class DocumentCrMetricsFileNameProvider : TemplateSqlFileNameProvider
{
public DocumentCrMetricsFileNameProvider(string projectName)
: base("Changes_Document_CR_Output_%project_name%.txt", projectName)
{ }
}
First, note that projectName remains the parameter for the constructor of these specialized classes. There are no globals here. Next, even though you've added a bit of plumbing code to your project, it's easier to decouple your classes for simpler testing: you can create a mocked implementation of ISqlFileNameProvider and return whatever you like to test the rest of the functionality without writing to real data files.
I would certainly advise against using a global property. The fact that you can specify the project name as a constructor parameter means that you can easily test that your class behaves the way you want it to. And even though you think that it will change during project lifetime, you can easily encounter a scenario where you temporarily need to switch the project name in runtime. I would advise against using globals.
In my Application a have a set of Data Providers and Redis Cache.
Each execution different providers are used, but they all store own Data in Redis:
hset ProviderOne Data "..."
hset ProviderTwo Data "..."
I would like have one method That will delete Data for all providers that are present in code.
del ProviderOne
del ProviderTwo
I have made next code:
void Main()
{
// Both providers have static field Hash with default value.
// I expected that static fields should be initialized when application starts,
// then initialization will call CacheRepository.Register<T>() method
// and all classes will register them self in CacheRepository.RegisteredHashes.
// But code start working only when i created this classes (at least once)
// new ProviderOne();
// new ProviderTwo();
CacheRepository.Reset();
}
public abstract class AbstractProvider
{
//...
}
public class ProviderOne : AbstractProvider
{
public static readonly string Hash =
CacheRepository.Register<ProviderOne>();
//...
}
public class ProviderTwo : AbstractProvider
{
public static readonly string Hash =
CacheRepository.Register<ProviderTwo>();
//...
}
public class CacheRepository
{
protected static Lazy<CacheRepository> LazyInstance = new Lazy<CacheRepository>();
public static CacheRepository Instance
{
get { return LazyInstance.Value; }
}
public ConcurrentBag<string> RegisteredHashes = new ConcurrentBag<string>();
public static string Register<T>()
{
string hash = typeof(T).Name;
if (!Instance.RegisteredHashes.Contains(hash))
{
Instance.RegisteredHashes.Add(hash);
}
return hash;
}
public static void Reset()
{
foreach (string registeredHash in Instance.RegisteredHashes)
{
Instance.Reset(registeredHash);
}
}
protected void Reset(string hash);
}
interface IData{}
interface IDataProvider
{
string GetRedisHash();
IData GetData();
}
intefrace IRedisRepository
{
}
How make it working?
You can just access any static method/property of your class - i.e. Provider1.Name:
public class Program
{
static void Main(string[] args)
{
Console.WriteLine(Provider1.Name + Provider2.Name);
Console.ReadLine();
}
}
In C# static constructor (one that initializes all static fields) is called only if any method of type is used as covered in C# specification 10.11 Static constructors:
The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
•An instance of the class is created.
•Any of the static members of the class are referenced.
Note that magical registration is very hard to write unit tests for - so while your approach would work it may be better to use some known system that allow registering objects that is convenient to test.
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..
Ok, so I know you can't have objects in a static class but i need a class that i can hold objects that are accessible from different classes. I am making a dll that will provide extended functionality to another program so i can't just inherit or pass classes around either. if need be i can just maybe make the properties of each object i need to be in the static class which would work but not be as friendly as i would like. anyone have any other ideas on how to accomplish something like this?
Actually, you can have objects in a static class -- they just have to be static objects.
For instance:
public static class SharedObjects
{
private static MyClass obj = new MyClass();
public static MyClass GetObj()
{
return obj;
}
}
And from elsewhere in your program you can call instance methods/properties/etc.:
SharedObjects.GetObj().MyInstanceMethod();
One option is to have a class with the accessors methods accessing a static object (or objects). The other parts of your system can use the class either as static or as a non-static. Here is the code:
public class GlobalInformation {
public static GlobalInformation CreateInstance() {
// Factory method through GlobalInformmation.CreateInstance()
return new GlobalInformation();
}
public GlobalInformation() {
// Regular use through new GlobalInformation()
}
static GlobalInformation() {
// Static initializer called once before class is used.
// e.g. initialize values:
_aString = "The string value";
}
public string AccessAString {
get {
return _aString;
}
}
public Foo AccessAnObject() {
return _anObject;
}
private static string _aString;
private static readonly Foo _anObject = new Foo();
}
Other parts of your system would use it as follows. Option 1:
var globalInfo = GlobalInformation.CreateInstance();
var aString = globalInfo.AssessAString;
var anObj = globalInfo.AccessAnObject();
Option 2:
var globalInfo = new GlobalInformation();
var aString = globalInfo.AssessAString;
var anObj = globalInfo.AccessAnObject();
Option 2 would be my preferred one (I'd remove the static factory method CreateInstance()) as you could change the implementation at any time including making (some of) the fields non-static. It would appear to be a regular class while sharing data.