Related
when they say static classes should not have state/side effects does that mean:
static void F(Human h)
{
h.Name = "asd";
}
is violating it?
Edit:
i have a private variable now called p which is an integer. It's never read at all throughout the entire program, so it can't affect any program flow.
is this violating "no side effects"?:
int p;
static void F(Human h)
{
p=123;
h.Name = "asd";
}
the input and output is still always the same in this case..
When you say "they", who are you refering to?
Anyways, moving on. A method such as what you presented is completely fine - if that's what you want it to do, then OK. No worries.
Similarly, it is completely valid for a static class to have some static state. Again, it could be that you would need that at some point.
The real thing to watch out for is something like
static class A
{
private static int x = InitX();
static A()
{
Console.WriteLine("A()");
}
private static int InitX()
{
Console.out.WriteLine("InitX()");
return 0;
}
...
}
If you use something along these lines, then you could easily be confused about when the static constructor is called and when InitX() is called. If you had some side effects / state changing that occurs like in this example, then that would be bad practice.
But as far as your actual question goes, those kind of state changes and side effects are fine.
Edit
Looking at your second example, and taking the rule precisely as it is stated, then, yes, you are in violation of it.
But...
Don't let that rule necessarily stop you from things like this. It can be very useful in some cases, e.g. when a method does intensive calculation, memoization is an easy way to reduce performance cost. While memoization technically has state and side-effects, the output is always the same for every input, which is the really important .
Side effects of a static member mean that it change the value of some other members in its container class. The static member in your case does not effect other members of its class and it is not violating the sentence you have mentioned.
EDIT
In the second example you've added by editting your question you are violating it.
It is perfectly acceptable for methods of a static class to change the state of objects that are passed to them. Indeed, that is the primary use for non-function static methods (since a non-function method which doesn't change the state of something would be pretty useless).
The pattern to be avoided is having a static class where methods have side-effects that are not limited to the passed-in objects or objects referenced by them. Suppose, for example, one had an embroidery-plotting class which had functions to select an embroidery module, and to scale, translate, or rotate future graphic operations. If multiple routines expect to do some drawing, it could be difficult to prevent device-selections or transformations done by one routine from affecting other routines. There are two common ways to resolve this problem:
Have all the static graphic routines accept a parameter which will hold a handle to the current device and world transform.
Have a non-static class which holds a device handle and world transform, and have it expose a full set of graphic methods.
In many cases, the best solution will be to have a class which uses the second approach for its external interface, but possibly uses the first method internally. The first approach is somewhat better with regard to the Single Responsibility Principle, but from an external calling standpoint, using class methods is often nicer than using static ones.
I have a piece of software written with fluent syntax. The method chain has a definitive "ending", before which nothing useful is actually done in the code (think NBuilder, or Linq-to-SQL's query generation not actually hitting the database until we iterate over our objects with, say, ToList()).
The problem I am having is there is confusion among other developers about proper usage of the code. They are neglecting to call the "ending" method (thus never actually "doing anything")!
I am interested in enforcing the usage of the return value of some of my methods so that we can never "end the chain" without calling that "Finalize()" or "Save()" method that actually does the work.
Consider the following code:
//The "factory" class the user will be dealing with
public class FluentClass
{
//The entry point for this software
public IntermediateClass<T> Init<T>()
{
return new IntermediateClass<T>();
}
}
//The class that actually does the work
public class IntermediateClass<T>
{
private List<T> _values;
//The user cannot call this constructor
internal IntermediateClass<T>()
{
_values = new List<T>();
}
//Once generated, they can call "setup" methods such as this
public IntermediateClass<T> With(T value)
{
var instance = new IntermediateClass<T>() { _values = _values };
instance._values.Add(value);
return instance;
}
//Picture "lazy loading" - you have to call this method to
//actually do anything worthwhile
public void Save()
{
var itemCount = _values.Count();
. . . //save to database, write a log, do some real work
}
}
As you can see, proper usage of this code would be something like:
new FluentClass().Init<int>().With(-1).With(300).With(42).Save();
The problem is that people are using it this way (thinking it achieves the same as the above):
new FluentClass().Init<int>().With(-1).With(300).With(42);
So pervasive is this problem that, with entirely good intentions, another developer once actually changed the name of the "Init" method to indicate that THAT method was doing the "real work" of the software.
Logic errors like these are very difficult to spot, and, of course, it compiles, because it is perfectly acceptable to call a method with a return value and just "pretend" it returns void. Visual Studio doesn't care if you do this; your software will still compile and run (although in some cases I believe it throws a warning). This is a great feature to have, of course. Imagine a simple "InsertToDatabase" method that returns the ID of the new row as an integer - it is easy to see that there are some cases where we need that ID, and some cases where we could do without it.
In the case of this piece of software, there is definitively never any reason to eschew that "Save" function at the end of the method chain. It is a very specialized utility, and the only gain comes from the final step.
I want somebody's software to fail at the compiler level if they call "With()" and not "Save()".
It seems like an impossible task by traditional means - but that's why I come to you guys. Is there an Attribute I can use to prevent a method from being "cast to void" or some such?
Note: The alternate way of achieving this goal that has already been suggested to me is writing a suite of unit tests to enforce this rule, and using something like http://www.testdriven.net to bind them to the compiler. This is an acceptable solution, but I am hoping for something more elegant.
I don't know of a way to enforce this at a compiler level. It's often requested for objects which implement IDisposable as well, but isn't really enforceable.
One potential option which can help, however, is to set up your class, in DEBUG only, to have a finalizer that logs/throws/etc. if Save() was never called. This can help you discover these runtime problems while debugging instead of relying on searching the code, etc.
However, make sure that, in release mode, this is not used, as it will incur a performance overhead since the addition of an unnecessary finalizer is very bad on GC performance.
You could require specific methods to use a callback like so:
new FluentClass().Init<int>(x =>
{
x.Save(y =>
{
y.With(-1),
y.With(300)
});
});
The with method returns some specific object, and the only way to get that object is by calling x.Save(), which itself has a callback that lets you set up your indeterminate number of with statements. So the init takes something like this:
public T Init<T>(Func<MyInitInputType, MySaveResultType> initSetup)
I can think of three a few solutions, not ideal.
AIUI what you want is a function which is called when the temporary variable goes out of scope (as in, when it becomes available for garbage collection, but will probably not be garbage collected for some time yet). (See: The difference between a destructor and a finalizer?) This hypothetical function would say "if you've constructed a query in this object but not called save, produce an error". C++/CLI calls this RAII, and in C++/CLI there is a concept of a "destructor" when the object isn't used any more, and a "finaliser" which is called when it's finally garbage collected. Very confusingly, C# has only a so-called destructor, but this is only called by the garbage collector (it would be valid for the framework to call it earlier, as if it were partially cleaning the object immediately, but AFAIK it doesn't do anything like that). So what you would like is a C++/CLI destructor. Unfortunately, AIUI this maps onto the concept of IDisposable, which exposes a dispose() method which can be called when a C++/CLI destructor would be called, or when the C# destructor is called -- but AIUI you still have to call "dispose" manually, which defeats the point?
Refactor the interface slightly to convey the concept more accurately. Call the init function something like "prepareQuery" or "AAA" or "initRememberToCallSaveOrThisWontDoAnything". (The last is an exaggeration, but it might be necessary to make the point).
This is more of a social problem than a technical problem. The interface should make it easy to do the right thing, but programmers do have to know how to use code! Get all the programmers together. Explain simply once-and-for-all this simple fact. If necessary have them all sign a piece of paper saying they understand, and if they wilfully continue to write code which doesn't do anythign they're worse than useless to the company and will be fired.
Fiddle with the way the operators are chained, eg. have each of the intermediateClass functions assemble an aggregate intermediateclass object containing all of the parameters (you mostly do it this was already (?)) but require an init-like function of the original class to take that as an argument, rather than have them chained after it, and then you can have save and the other functions return two different class types (with essentially the same contents), and have init only accept a class of the correct type.
The fact that it's still a problem suggests that either your coworkers need a helpful reminder, or they're rather sub-par, or the interface wasn't very clear (perhaps its perfectly good, but the author didn't realise it wouldn't be clear if you only used it in passing rather than getting to know it), or you yourself have misunderstood the situation. A technical solution would be good, but you should probably think about why the problem occurred and how to communicate more clearly, probably asking someone senior's input.
After great deliberation and trial and error, it turns out that throwing an exception from the Finalize() method was not going to work for me. Apparently, you simply can't do that; the exception gets eaten up, because garbage collection operates non-deterministically. I was unable to get the software to call Dispose() automatically from the destructor either. Jack V.'s comment explains this well; here was the link he posted, for redundancy/emphasis:
The difference between a destructor and a finalizer?
Changing the syntax to use a callback was a clever way to make the behavior foolproof, but the agreed-upon syntax was fixed, and I had to work with it. Our company is all about fluent method chains. I was also a fan of the "out parameter" solution to be honest, but again, the bottom line is the method signatures simply could not change.
Helpful information about my particular problem includes the fact that my software is only ever to be run as part of a suite of unit tests - so efficiency is not a problem.
What I ended up doing was use Mono.Cecil to Reflect upon the Calling Assembly (the code calling into my software). Note that System.Reflection was insufficient for my purposes, because it cannot pinpoint method references, but I still needed(?) to use it to get the "calling assembly" itself (Mono.Cecil remains underdocumented, so it's possible I just need to get more familiar with it in order to do away with System.Reflection altogether; that remains to be seen....)
I placed the Mono.Cecil code in the Init() method, and the structure now looks something like:
public IntermediateClass<T> Init<T>()
{
ValidateUsage(Assembly.GetCallingAssembly());
return new IntermediateClass<T>();
}
void ValidateUsage(Assembly assembly)
{
// 1) Use Mono.Cecil to inspect the codebase inside the assembly
var assemblyLocation = assembly.CodeBase.Replace("file:///", "");
var monoCecilAssembly = AssemblyFactory.GetAssembly(assemblyLocation);
// 2) Retrieve the list of Instructions in the calling method
var methods = monoCecilAssembly.Modules...Types...Methods...Instructions
// (It's a little more complicated than that...
// if anybody would like more specific information on how I got this,
// let me know... I just didn't want to clutter up this post)
// 3) Those instructions refer to OpCodes and Operands....
// Defining "invalid method" as a method that calls "Init" but not "Save"
var methodCallingInit = method.Body.Instructions.Any
(instruction => instruction.OpCode.Name.Equals("callvirt")
&& instruction.Operand is IMethodReference
&& instruction.Operand.ToString.Equals(INITMETHODSIGNATURE);
var methodNotCallingSave = !method.Body.Instructions.Any
(instruction => instruction.OpCode.Name.Equals("callvirt")
&& instruction.Operand is IMethodReference
&& instruction.Operand.ToString.Equals(SAVEMETHODSIGNATURE);
var methodInvalid = methodCallingInit && methodNotCallingSave;
// Note: this is partially pseudocode;
// It doesn't 100% faithfully represent either Mono.Cecil's syntax or my own
// There are actually a lot of annoying casts involved, omitted for sanity
// 4) Obviously, if the method is invalid, throw
if (methodInvalid)
{
throw new Exception(String.Format("Bad developer! BAD! {0}", method.Name));
}
}
Trust me, the actual code is even uglier looking than my pseudocode.... :-)
But Mono.Cecil just might be my new favorite toy.
I now have a method that refuses to be run its main body unless the calling code "promises" to also call a second method afterwards. It's like a strange kind of code contract. I'm actually thinking about making this generic and reusable. Would any of you have a use for such a thing? Say, if it were an attribute?
What if you made it so Init and With don't return objects of type FluentClass? Have them return, e.g., UninitializedFluentClass which wraps a FluentClass object. Then calling .Save(0 on the UnitializedFluentClass object calls it on the wrapped FluentClass object and returns it. If they don't call Save they don't get a FluentClass object.
In Debug mode beside implementing IDisposable you can setup a timer that will throw a exception after 1 second if the resultmethod has not been called.
Use an out parameter! All the outs must be used.
Edit: I am not sure of it will help, tho...
It would break the fluent syntax.
It's generally agreed upon that relying heavily on global stuff is to be avoided. Wouldn't using static classes and methods be the same thing?
Global data is bad. However many issues can be avoided by working with static methods.
I'm going to take the position of Rich Hickey on this one and explain it like this:
To build the most reliable systems in C# use static methods and classes, but not global data. For instance if you hand in a data object into a static method, and that static method does not access any static data, then you can be assured that given that input data the output of the function will always be the same. This is the position taken by Erlang, Lisp, Clojure, and every other Functional Programming language.
Using static methods can greatly simplify multi-threaded coding, since, if programmed correctly, only one thread will have access to a given set of data at a time. And that is really what it comes down to. Having global data is bad since it is a state that can be changed by who knows what thread, and any time. Static methods however allow for very clean code that can be tested in smaller increments.
I know this will be hotly debated, as it flies in the face of C#'s OOP thought process, but I have found that the more static methods I use, the cleaner and more reliable my code is.
This video explains it better than I can, but shows how immutable data, and static methods can produce some extremely thread-safe code.
Let me clarify a bit more some issues with Global Data. Constant (or read-only) global data isn't nearly as big of an issue as mutable (read/write) global data. Therefore if it makes sense to have a global cache of data, use global data! To some extent every application that uses a database will have that, since we could say that all a SQL Database is one massive global variable that holds data.
So making a blanket statement like I did above is probably a bit strong. Instead, let's say that having global data introduces many issues that can be avoid by having local data instead.
Some languages such as Erlang get around this issue by having the cache in a separate thread that handles all requests for that data. This way you know that all requests and modifications to that data will be atomic and the global cache will not be left in some unknown state.
static doesn't necessarely mean global. Classes and members can be static private, hence only applying to the specific class. That said, having too many public static members instead of using appropriate ways to pass data (method calls, callbacks, etc.) is generally bad design.
If you're trying to be purist about your OO development, then statics probably don't fit the mold.
However the real world is messier than theory, and statics are often a very useful way to solve some development problems. Use them when appropriate, and in moderation.
As an addition to whatever else is said, final static variables are just fine; constants are a good thing. The only exception to that is when/if you should just move them to a properties file, to be easier to change.
Mutable static variables are bad because they're just global state. The best discussion I know of about this is here, under the heading "Why Global Variables Should Be Avoided When Unnecessary".
Static methods have several drawbacks that often make them undesirable - the biggest one being that they cannot be used polymorphically.
First, why are the old global variables so bad? Because it is state that is accessible from anywhere, any time. Hard to track.
There are no such problems with static methods.
That leaves static fields (variables). If you declared a public static field in a class, that would truly be a global variable and it would be bad.
But make the static field private and most problems are solved. Or better, they are limited to the containing class and that makes them solvable.
public class Foo
{
private static int counter = 0;
public static int getCounterValue()
{
return counter;
}
//...
public Foo()
{
//other tasks
counter++;
}
}
In the code above you can see that we count how many Foo objects were created. This can be useful in many cases.
The static keyword is not global, it's telling you that it's on class level, which can be very useful in various cases. So, in conclusion, class level things are static, object level things are not static.
Static methods are used to implement traits in Scala. In C#, extension methods (which are static) fulfill that role in part. That could be seen, as the DCI proponents state, as a "higher order form of polymorphism".
Also, static methods can be used to implement functions. This is what F# uses to implement modules. (And also VB.NET.) Functions are useful for (unsurprisingly) functional-programming. And sometimes they're just the way something should be modeled (like the "functions" in the Math class). Again, C# comes close here.
I think the bad thing about global variables is the idea of having global state - variables that can be manipulated anywhere and tend to cause unintended side effects in far-flung areas of a program.
Static data would be similar to global variables in that they introduce a kind of global state. Static methods though are not nearly as bad, assuming they are stateless.
Not entirely. Static actually determines when, where and how often something is instantiated, not who has access to it.
Very often it happens that I have private methods which become very big and contain repeating tasks but these tasks are so specific that it doesn't make sense to make them available to any other code part.
So it would be really great to be able to create 'inner methods' in this case.
Is there any technical (or even philosophical?) limitation that prevents C# from giving us this? Or did I miss something?
Update from 2016: This is coming and it's called a 'local function'. See marked answer.
Well, we can have "anonymous methods" defined inside a function (I don't suggest using them to organize a large method):
void test() {
Action t = () => Console.WriteLine("hello world"); // C# 3.0+
// Action t = delegate { Console.WriteLine("hello world"); }; // C# 2.0+
t();
}
If something is long and complicated than usually its good practise to refactor it to a separate class (either normal or static - depending on context) - there you can have private methods which will be specific for this functionality only.
I know a lot of people dont like regions but this is a case where they could prove useful by grouping your specific methods into a region.
Could you give a more concrete example? After reading your post I have the following impression, which is of course only a guess, due to limited informations:
Private methods are not available outside your class, so they are hidden from any other code anyway.
If you want to hide private methods from other code in the same class, your class might be to big and might violate the single responsibility rule.
Have a look at anonymous delegates an lambda expressions. It's not exactly what you asked for, but they might solve most of your problems.
Achim
If your method becomes too big, consider putting it in a separate class, or to create private helper methods. Generally I create a new method whenever I would normally have written a comment.
The better solution is to refactor this method to separate class. Create instance of this class as private field in your initial class. Make the big method public and refactor big method into several private methods, so it will be much clear what it does.
Seems like we're going to get exactly what I wanted with Local Functions in C# 7 / Visual Studio 15:
https://github.com/dotnet/roslyn/issues/2930
private int SomeMethodExposedToObjectMembers(int input)
{
int InnerMethod(bool b)
{
// TODO: Change return based on parameter b
return 0;
}
var calculation = 0;
// TODO: Some calculations based on input, store result in calculation
if (calculation > 0) return InnerMethod(true);
return InnerMethod(false);
}
Too bad I had to wait more than 7 years for this :-)
See also other answers for earlier versions of C#.
Hey all - I have an app where I'm authenticating the user. They pass username and password. I pass the username and password to a class that has a static method. For example it'm calling a method with the signature below:
public class Security
{
public static bool Security.Member_Authenticate (string username, string password)
{ //do stuff}
}
If I have 1000 people hitting this at once, will I have any problems with the returns of the method bleeding into others? I mean, since the methods are static, will there be issues with the a person getting authenticated when in fact they shouldn't be but the person before them was successfully authenticated ASP.Net returns a mismatched result due to the method being static? I've read of issues with static properties vs viewstate but am a bit confused on static methods. If this is a bad way of doing this,what's the prefered way?
This will not happen. When a method is Static (or Shared in VB.NET), then you're safe as long as the method doesn't rely on anything other than the inputs to figure something out. As long as you're not modifying any public variables or objects from anywhere else, you're fine.
A static method is just fine as long as it is not using any of persistent data between successive calls. I am guessing that your method simply runs a query on the database and returns true/false based on that.
In this scenario, I think the static method should work without a problem, regardless of how many calls you make to it.
ASP.net does use all sorts of under-the-hood thread pooling, which can make static methods and fields dicey.
However, you can avoid most threading issues with a static method by using only locally-scoped variables in that method. That way, each thread (user) will have their own in-memory copy of all the variables being used.
If you use higher-scoped variables, make sure to make all access to them thread-conscious.
Throwing exceptions is not a good practice as it makes the .net runtime to create extra infrastructure for catching them. To verify this create a class and and populate it with some random values using a loop. Make the loop iterate for a large counter like 10,000. Record the time it takes to create the list. Now enclose the instance creation in a try..catch block and record the time. Now, you can see the exceptionally large difference.
e.g
for(int i=0; i<10000; i++){
Employee emp = new Employee();
emp.Name = "Random Name" + i.ToString();
}
Versus
for(int i=0; i<10000; i++){
try{
Employee emp = new Employee();
emp.Name = "Random Name" + i.ToString();
}catch{}
}
Although there is no fixed solution whether to throw exception or not, it is a best practice to create alternate flows in your program and handle every condition with proper return values. Exceptions should be thrown only when the situation can be justified as exceptional.
While I can see the value of the static method in regards to the perceived performance gains, I believe the real issue here is whether the gains (and risks) are worth the maintenance kludge and security weakness you are potentially creating. I believe that most people would warn you away from providing a public method that accepts an user credentials and returns success or failure. It potentially provides an easy a method for hacking.
So, my point is philosophical. Otherwise, I agree with others who have pointed out that restricting the code to use local variables should ensure that you do not have any problems with side effects due to concurrent access of the method, even on different threads, i.e., if you invoke the method on a ThreadPool thread.
Maybe it's better to use public static void Authenticate(string, string) which throws an exception if something goes wrong (return false in original method) ?
This is a good .NET style. Boolean function return-type is the C style and is obsolete.
Why don't you have the user class with username and password and a method that is called authenticate?