Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I have read so many conflicting opinions on the use of static methods that my head hurts. Consider the following:
In most of my CRUD applications I use a SqlDataHandler class to handle the interactions with the database for a class (or in some cases group of classes). See below:
public abstract SqlDataHandler
{
#region Properties
protected static string ConnectionString { get; set; }
#endregion
#region Methods
protected static DataTable GetDataTable(SqlCommand GetTableCommand)
{
...
}
#endregion
}
public AccountSqlDataHandler : SqlDataHandler
{
#region Methods
public static DataTable GetAccountHistory()
{
SqlCommand getAccountHistoryCommand;
...
return AccountSqlDataHandler.GetDataTable(getAccountHistoryCommand);
}
#endregion
#region Ctors
static AccountSqlDataHandler()
{
AccountSqlDataHandler.ConnectionString = "Connection string for account database";
}
#endregion
}
public Account
{
#region Properties
public List<HistoryItem> AccountHistory
{
get
{
List<HistoryItem> accountHistory;
accountHistory =
this.getItemsFromDataTable(AccountSqlDataHandler.GetAccountHistory());
return accountHistory;
}
}
#endregion
}
As I see it if I use member methods, then either I have to create an AccountSqlDataHandler instance each time, or create an AccountSqlDataHandler member in the Account class. I don't see any advantage to doing this, but from what I'm reading there is an advantage. I would like to understand what it is before I blindly change my methodology.
A good rule of thumb is to use a static method if the method is not dependent on a specific instance. I.E.
public static int Add (x, y)
{
return x + y;
}
And you should use instance methods if you do depend on the instance.
public int Add(x)
{
return this.y + x;
}
Now your specific issue is Maybe you connect to multiple databases, or you have multiple connection strings.
If you do, than it makes perfect sense to instantiate your sql data handlers. but if you don't than there's not much need.
Nope. In fact, there will be a nice bug for you when you add and use a second handler.
Try this code out (hopefully you'll notice the similarity with your ConnectionString property):
internal class Program
{
private static void Main(string[] args)
{
var bravo = new Bravo();
var charlie = new Charlie();
Console.WriteLine(bravo.GetValue());
Console.WriteLine(charlie.GetValue());
Bravo.EchoValue();
Charlie.EchoValue();
}
}
public abstract class Alpha
{
protected static string Value { get; set; }
public abstract string GetValue();
}
public class Bravo : Alpha
{
static Bravo()
{
Value = "bravo";
}
public override string GetValue()
{
return Value;
}
public static void EchoValue()
{
Console.WriteLine(Value);
}
}
public class Charlie : Alpha
{
static Charlie()
{
Value = "charlie";
}
public override string GetValue()
{
return Value;
}
public static void EchoValue()
{
Console.WriteLine(Value);
}
}
Output:
charlie
charlie
charlie
charlie
Press any key to continue . . .
ConnectionString is effectively shared state and modifying it in static constructors means that the last static constructor call will set the state for the entire application (until something sets it to what it wants it to be but then this must be the rule and then the static constructors are pointless). This will inevitably lead to the why is my accounts query hitting the orders database? problems (because a developer didn't explicitly set the connection string prior to every usage) as well as kill any chance at this application working in a multi-database context.
In general static should be something when that behavior logically belongs to a class or type instead of its instances and static data when that data is shared among all instances.
In your case it looks like you want a Singleton for each database. Take a look at that pattern. Many times I've seen singleton being implemented as static classes/methods which is not correct.
Another thing in .NET, there is a general guideline that static methods are (should be) thread safe but instance methods are not. You have to take care of this guideline when implementing static methods.
Related
I am currently writing a software program for a tour, made up of exhibits. The exhibit object, at any given point, is in one of four states, defined by the ExhibitStates enum:
private enum ExhibitState { Ready, Active, Complete, Inactive };
For developers who will be setting up exhibits, there are only two "starting" states that I want them to be able to choose from:
public enum StartingExhibitState { Ready, Inactive };
Currently, I have it set up so that upon being initialized, the exhibit will immediately set its state to match its starting state, like so:
switch (startingState) {
case StartingExhibitState.Ready:
SetState(ExhibitState.Ready);
break;
case StartingExhibitState.Inactive:
SetState(ExhibitState.Inactive);
break;
}
I found myself wondering today if this was the best practice. Is there a better way to restrict which enum options are public and which are private? Or is it best to simply have the two separate enums?
Thank you so much for your time.
If you create second enum - your intents will be very clearly explained through signature of setting method
public enum ExhibitState
{
Inactive = 0,
Active = 1,
Ready = 2,
Complete = 3
};
public enum InitialStates
{
Inactive = ExhibitState.Inactive,
Ready = ExhibitState.Ready
};
public void SetInitial(InitialStates state)
{
SetState((ExhibitState)state);
}
If you go further you can add compiler help for preventing passing wrong values to the method.
public sealed class InitialState
{
public static readonly InitialState Initial = new InitialState(ExhibitState.Initial);
public static readonly InitialState Ready = new InitialState(ExhibitState.Ready);
public ExhibitState State { get; }
private InitialState(ExhibitState state)
{
State = state;
}
}
Constructor made private to prevent instantiating class from else where.
Class marked as sealed to prevent deriving and changing it behaviour.
Then your method will look like
public void SetInitial(InitialState start)
{
SetState(start.State);
}
// use it
SetInitial(InitialState.Initial);
SetInitial(InitialState.Ready);
Nothing else cannot be passed, until you change code of InitialState class.
Instead of using an enum (or two of them), you could use a class-based approach:
public abstract class ExhibitState
{
public static ExhibitInitialState Ready { get { return new ExhibitReadyState(); } }
public static ExhibitInitialState Inactive { get { return new ExhibitInactiveState(); } }
public static ExhibitState Complete { get { return new ExhibitCompleteState(); } }
public static ExhibitState Active { get { return new ExhibitActiveState(); } }
private class ExhibitReadyState : ExhibitInitialState {}
private class ExhibitInactiveState : ExhibitInitialState {}
private class ExhibitCompleteState : ExhibitState {}
private class ExhibitActiveState : ExhibitState {}
}
public abstract class ExhibitInitialState : ExhibitState {}
The above sample shows a simple approach. Usually, you'd not create a new instance of a state in the get methods, but have static instances so that comparing is easier.
Similar to an enum, you could still type ExhibitState.Ready or the other states. In addition, the base class ExhibitInitialState allows you to limit the states that can be set initially:
public void SetInitial(ExhibitInitialState initState) { ... }
In comparison to the approach that #Fabio proposed, you'd have the benefit that you could not mix up the values. Furthermore and especially relevant for states: is very common that the behavior should also change for a specific state. With this class-based approach, you could implement this behavior in the specific ExhibitState implementations and by that avoid lots of switch statements that are likely to exist in an enum-based approach.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Related to C# - Is there a better alternative than this to 'switch on type'?
I need to 'switch on types': given a parameter of type T, find and execute a method of the form void Method (T param).
This could be solved with a switch statement or a Dictionary<Type, Action>, however I would like to avoid the casts necessary in such scenarios.
I couldn't find the following approach mentioned in the above (or similar) questions:
Create a static generic type that acts as collection:
public static class Commands<T> {
public static Action<T> Handler;
}
Create a repository which uses that type like a type-safe dictionary:
public class CommandRepository {
public void Register<T>(Action<T> handler) {
Commands<T>.Handler = handler;
}
public void Run<T>(T parameter) {
// null checks etc.
Commands<T>.Handler(parameter);
}
}
Example usage:
public void CreateUser(CreateUserParams p) {
Console.WriteLine("Creating " + p.Name);
}
// ...
var repo = new CommandRepository();
repo.Register<CreateUserParams>(CreateUser);
repo.Register<DeleteUserParams>(DeleteUser);
repo.Run(new CreateUserParams { Name = "test" });
repo.Run(new DeleteUserParams { Name = "test" });
As mentioned before, the same behavior could be achieved with a Dictionary<Type, Action> in the ComandRepository, but then I would have to cast either the method parameter or, if I use interfaces instead of Action, cast to an IFoo<T> after acquiring an dictionary item.
My question is: Is it OK to (ab-)use generic types like that (given a large number of possible values for T)?
(Bonus question) If it isn't OK, why exactly not? What are the costs / negative effects this would cause?
A final note: I realize this doesn't work for type hierarchies or interfaces. Type T must be matched exactly, which in my scenario is fine.
Edit: I found out that Jil, a JSON serializer, also relies on this pattern. See the TypeCache type, which stores a delegate to serialize an object of type T (as far as I've understood from skimming through code). Since this TypeCache will store a large amount of types I suppose the pattern is generally not problematic.
It would still be interesting to know whether types or their static members need to be garbage collected or if there are other performance implications that need to be considered.
The approach you suggest is workable but has the disadvantage that your repository is effectively a singleton. If you ever find yourself needing a repository which doesn't behave like a singleton, you may find the ConditionalWeakTable[1] type helpful. The trick with using one of those is that for each type of interest you would have a singleton ConditionalWeakTable which maps your objects to the thing (if any) associated with that type. That class is only available in .NET 4.0, but can do some wonderful things.
[1] http://msdn.microsoft.com/en-us/library/dd287757.aspx
As an example, suppose one wanted a type OutTypeKeyedDictionary which supports a SetValue<T>(T Value) and bool TryGetValue<T>(out T Value). One could use a static class family OutputMappers<T>, each class of which which held a singleton instance of ConditionalWeakTable<OutTypeKeyedDictionary, T>. The OutTypeKeyedDictionary wouldn't actually have any fields(!); rather, each instance would be used purely as an identity token which would be used as a ConditionalWeakTable key. Incidentally, the reason that class is in the CompilerServices namespace rather than Collections is that it is used heavily by things like ExpandoObject.
The usual way to implement double dispatch in language like C# that provide only single dispatch, is the Visitor pattern. Your example would look as follows:
Interfaces:
interface IVisitor
{
void VisitCreateUserParams(CreateUserParams p);
void VisitDeleteUserParams(DeleteUserParams p);
}
interface IParams
{
void Accept(IVisitor visitor);
}
Command parameters:
class CreateUserParams : IParams
{
public void Accept(IVisitor visitor) { visitor.VisitCreateUserParams(this); }
public string Name { get; set; }
}
class DeleteUserParams : IParams
{
public void Accept(IVisitor visitor) { visitor.VisitDeleteUserParams(this); }
public string Name { get; set; }
}
Commands:
class CommandHandler : IVisitor
{
public void VisitCreateUserParams(CreateUserParams p)
{
Console.WriteLine("Creating " + p.Name);
}
public void VisitDeleteUserParams(DeleteUserParams p)
{
Console.WriteLine("Deleting " + p.Name);
}
}
Example usage:
var handler = new CommandHandler();
new CreateUserParams { Name = "test" }.Accept(handler);
new DeleteUserParams { Name = "test" }.Accept(handler);
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I sometimes need to go online and find a tutorial for something. I am often finding that some people put code like this:
this.button1.Text = "Random Text";
Then I find code that is just like this:
button1.Text = "Random Text";
Is it better to use the this.whatever or does it not matter?
It depends. Here's an example class:
class A
{
private int count;
public A(int count)
{
this.count = count;
}
}
In this case, the "this." is mandatory because it disambiguates the reference on the left of the assignment. Without it, it is not clear to you reading the code whether "count" would refer to the parameter or the field. (It is clear to the compiler, which has rules to follow.) But in most cases, it is purely a matter of preference.
Write all your code to emphasize salient points to the reader. If you feel that it is important for the reader to clearly understand that an identifier refers to an instance member then use this. If you feel that its an unimportant and distracting implementation detail, don't. Use good judgment to make your code readable.
this is just to make it clear, in some cases we have to use this:
Differentiate between parameter and local member:
//local member
object item;
private void SomeMethod(object item){
this.item = item;//must use this
}
Pass the current class instance into another method:
public class SomeClass {
private void SomeMethod(SomeClass obj){
//....
}
private void AnotherMethod(){
SomeMethod(this);//pass the current instance into SomeMethod
//.....
}
}
Use in extension methods:
public static class SomeClassExtension {
public static void SomeClassMethod(this SomeClass obj){
//use obj as a reference to the object calling this method...
}
}
Call a constructor from another constructor (with different signature):
public Form1(string s) : this() {//Call the Form1() before executing other code in Form1(string s)
//......
}
Use for declaring indexers:
public class SomeClass {
//declare an index returning a string
public string this[int index] {
get {return ...}
set { ... }
}
}
Use auto-properties in struct:
public struct SomeStruct {
public object AutoProp1 {get;set;}
public object AutoProp2 {get;set;}
public SomeStruct() : this() //must use this
{
AutoProp1 = someObject;
AutoProp2 = someObject;
}
}
Cast the current instance to the based classes/types:
public class ClassB : ClassC {
//...
}
public class ClassA : ClassB {
public ClassA(){
((ClassC)this).MemberOfClassC ... ;//There might be some member in ClassC
//which is overridden in ClassA or ClassB, casting to ClassC can help we invoke the original member instead of the overridden one.
}
}
There might be some other uses of this, however I'll update later if I think out.
It does not matter, it is a matter of style. I tend to omit this, since it is just extra code to mentally parse.
The only case it matters is when there is a naming conflict between local and instance variables, in which case this can be used to disambiguate between a field and a local variable.
Here is an example of the type of situation where it does matter:
public class Foo
{
private string x;
public Foo(string x)
{
// x = x; Assigns local parameter x to x, not what we want
this.x = x; // Assigns instance variable x to local parameter x: this disambiguates between the two.
}
}
an example of using this can be to access class variable when you already have a similar variable in the scope. Otherwise it is mostly of choice.
Example
public class Test
{
public string firstName { get; set; }
public void temp(string firstName)
{
firstName = this.firstName;
}
}
In regards to fields the only case where this is explicitly needed is when there is a naming conflict:
public class Foo
{
private string bar;
public Foo(string bar)
{
this.bar = bar;
}
}
So some will prepend an underscore:
public class Foo
{
private string _bar;
public Foo(string bar)
{
_bar = bar;
}
}
Usually it will not matter. This reason why you might use this. is to explicit say that you want to reference a property/field that belong to the current class.
Again, there are not many occasions when you are likely to need this, but for example you might have a local variable with the same name as a class level property/field. Then you could use this..
For example:
class MyClass
{
string s = "1";
void MyFunction(string s)
{
//s = local value as passed in to function
//this.s = "1"
}
}
It doesn't usually matter. The this keyword "refers to the current instance of the class and is also used as a modifier of the first parameter of an extension method."
Check out this article.
http://msdn.microsoft.com/en-us/library/dk1507sz.aspx
generally it doesn't matter, but if you pass in a variable called, say button1, to a class method that already has a member called button1, then you'll need to disambiguate which one you really meant.
This is probably why people now use this. to explicitly say which variable you meant, if you use this practice all the time, you'll not get it wrong in the few cases where its important.
Of course, you could ensure that all member variables are uniquely named, say with a prefix like m_, but that's fallen out of fashion nowadays, people prefer to write out this.
It really depends on the situation.
http://msdn.microsoft.com/en-us/library/dk1507sz(v=vs.80).aspx
To qualify members hidden by similar names
To pass an object as a parameter to other methods
To declare indexers
As others have already pointed out, it is useful in distinguishing field/property with method variables, One other place where this is required is to invoke Extension methods on current instance. For example this.ExtensionMethod(); would work, but not just ExtensionMethod();
Other than that, its a matter of personal choice, some call it redundant and some like to use it. It totally depends on you and your team.
Personally I like to use this with class members, specially for Forms method if working on code-behind of winform, like this.Close();
For more discussion when to use this see: When do you use the "this" keyword?
I have a method which should return a snapshot of the current state, and another method which restores that state.
public class MachineModel
{
public Snapshot CurrentSnapshot { get; }
public void RestoreSnapshot (Snapshot saved) { /* etc */ };
}
The state Snapshot class should be completely opaque to the caller--no visible methods or properties--but its properties have to be visible within the MachineModel class. I could obviously do this by downcasting, i.e. have CurrentSnapshot return an object, and have RestoreSnapshot accept an object argument which it casts back to a Snapshot.
But forced casting like that makes me feel dirty. What's the best alternate design that allows me to be both type-safe and opaque?
Update with solution:
I wound up doing a combination of the accepted answer and the suggestion about interfaces. The Snapshot class was made a public abstract class, with a private implementation inside MachineModel:
public class MachineModel
{
public abstract class Snapshot
{
protected internal Snapshot() {}
abstract internal void Restore(MachineModel model);
}
private class SnapshotImpl : Snapshot
{
/* etc */
}
public void Restore(Snapshot state)
{
state.Restore(this);
}
}
Because the constructor and methods of Snapshot are internal, callers from outside the assembly see it as a completely opaque and cannot inherit from it. Callers within the assembly could call Snapshot.Restore rather than MachineModel.Restore, but that's not a big problem. Furthermore, in practice you could never implement Snapshot.Restore without access to MachineModel's private members, which should dissuade people from trying to do so.
Can MachineModel and Snapshot be in the same assembly, and callers in a different assembly? If so, Snapshot could be a public class but with entirely internal members.
I could obviously do this by
downcasting, i.e. have CurrentSnapshot
return an object, and have
RestoreSnapshot accept an object
argument which it casts back to a
Snapshot.
The problem is that somebody could then pass an instance of an object which is not Snapshot.
If you introduce an interface ISnapshot which exposes no methods, and only one implementation exists, you can almost ensure type-safety at the price of a downcast.
I say almost, because you can not completely prevent somebody from creating another implementation of ISnapshot and pass it, which would break. But I feel like that should provide the desired level of information hiding.
You could reverse the dependency and make Snapshot a child (nested class) of MachineModel. Then Snapshot only has a public (or internal) Restore() method which takes as a parameter an instance of MachineModel. Because Snapshot is defined as a child of MachineModel, it can see MachineModel's private fields.
To restore the state, you have two options in the example below. You can call Snapshot.RestoreState(MachineModel) or MachineModel.Restore(Snapshot)*.
public class MachineModel
{
public class Snapshot
{
int _mmPrivateField;
public Snapshot(MachineModel mm)
{
// get mm's state
_mmPrivateField = mm._privateField;
}
public void RestoreState(MachineModel mm)
{
// restore mm's state
mm._privateField = _mmPrivateField;
}
}
int _privateField;
public Snapshot CurrentSnapshot
{
get { return new Snapshot(this); }
}
public void RestoreState(Snapshot ss)
{
ss.Restore(this);
}
}
Example:
MachineModel mm1 = new MachineModel();
MachineModel.Snapshot ss = mm1.CurrentSnapshot;
MachineModel mm2 = new MachineModel();
mm2.RestoreState(ss);
* It would be neater to have Snapshot.RestoreState() as internal and put all callers outside the assembly, so the only way to do a restore is via MachineModel.RestoreState(). But you mentioned on Jon's answer that there will be callers inside the same assembly, so there isn't much point.
This is an old question, but i was looking for something very similar and I ended up here and between the information reported here and some other I came up with this solution, maybe is a little overkill, but this way the state object is fully opaque, even at the assembly level
class Program
{
static void Main(string[] args)
{
DoSomething l_Class = new DoSomething();
Console.WriteLine("Seed: {0}", l_Class.Seed);
Console.WriteLine("Saving State");
DoSomething.SomeState l_State = l_Class.Save_State();
l_Class.Regen_Seed();
Console.WriteLine("Regenerated Seed: {0}", l_Class.Seed);
Console.WriteLine("Restoring State");
l_Class.Restore_State(l_State);
Console.WriteLine("Restored Seed: {0}", l_Class.Seed);
Console.ReadKey();
}
}
class DoSomething
{
static Func<DoSomething, SomeState> g_SomeState_Ctor;
static DoSomething()
{
Type type = typeof(SomeState);
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
}
Random c_Rand = new Random();
public DoSomething()
{
Seed = c_Rand.Next();
}
public SomeState Save_State()
{
return g_SomeState_Ctor(this);
}
public void Restore_State(SomeState f_State)
{
((ISomeState)f_State).Restore_State(this);
}
public void Regen_Seed()
{
Seed = c_Rand.Next();
}
public int Seed { get; private set; }
public class SomeState : ISomeState
{
static SomeState()
{
g_SomeState_Ctor = (DoSomething f_Source) => { return new SomeState(f_Source); };
}
private SomeState(DoSomething f_Source) { Seed = f_Source.Seed; }
void ISomeState.Restore_State(DoSomething f_Source)
{
f_Source.Seed = Seed;
}
int Seed { get; set; }
}
private interface ISomeState
{
void Restore_State(DoSomething f_Source);
}
}
Does anybody have useful example of this assignment inside a C# method? I have been asked for it once during job interview, and I am still interested in answer myself.
The other answers are incorrect when they say you cannot assign to 'this'. True, you can't for a class type, but you can for a struct type:
public struct MyValueType
{
public int Id;
public void Swap(ref MyValueType other)
{
MyValueType temp = this;
this = other;
other = temp;
}
}
At any point a struct can alter itself by assigning to 'this' like so.
using the this keyword ensures that only variables and methods scoped in the current type are accessed. This can be used when you have a naming conflict between a field/property and a local variable or method parameter.
Typically used in constructors:
private readonly IProvider provider;
public MyClass(IProvider provider)
{
this.provider = provider;
}
In this example we assign the parameter provider to the private field provider.
only correct place for this from syntax point of view, is Extension methods in C# 3.0 when you specify first parameter of method as foo(ftype this, ...). and then can use this extension for any instance of ftype. But is's just syntax and not real this ovveride operation.
if you're asked to assign something to this, there's quite a few examples. One that comes to mind is telling a control who his daddy is:
class frmMain
{
void InitializeComponents()
{
btnOK = new Button();
btnOK.Parent = this;
}
}
I know this question has long been answered and discussion has stopped, but here's a case I didn't see mentioned anywhere on the interwebs and thought it may be useful to share here.
I've used this to maintain immutability of members while still supporting serialization. Consider a struct defined like this:
public struct SampleStruct : IXmlSerializable
{
private readonly int _data;
public int Data { get { return _data; } }
public SampleStruct(int data)
{
_data = data;
}
#region IXmlSerializableMembers
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader)
{
this = new SampleStruct(int.Parse(reader.ReadString()));
}
public void WriteXml(XmlWriter writer
{
writer.WriteString(data.ToString());
}
#endregion
}
Since we're allowed to overwrite this, we can maintain the immutability of _data held within a single instance. This has the added benefit of when deserializing new values you're guaranteed a fresh instance, which is sometimes a nice guarantee!
}
You cannot overwrite "this". It points to the current object instance.