Global member vs. passing parameters - c#

I have a ASP.NET project, in which I have a method with 10 local variables. This method calls about 10 other methods. 3 of the called methods need all the variables. Is it considered good practice to turn all those variables into global members, and then they don't have to passed as parameters?

If you want to pass complex state around, package it in an object - i.e.
public class Foo {
public string Key {get;set;}
public decimal Quantity {get;set;}
// etc
}
And have the methods accept this object as an argument. Then you just create an instance of this and pass it along.
Global is a big no-no; ASP.NET is highly threaded - this would be a nightmare. Per-request state is possible, but a bit messy.

Do these variables relate to each other, either all of them or perhaps into a few groups? If so, encapsulate them into a type. So you might have half of your variables relating to a user, and half relating to a requested operation - and suddenly your method taking 10 variables only takes 2.
Making things global is almost always the wrong way to go.

create a structure instead and pass the structure instead of passing those 10 parameters
Eg :
public struct user
{
public string FirstName;
public string LastName;
public string zilionotherproperties;
public bool SearchByLastNameOnly;
public datetime date1;
}

Well, it depends entirely on what you mean by "global members".
If, considering you're writing an ASP.NET application, you mean session/application-based cache values, then it depends. There's performance implications so you should measure to see if it has any impact on your app.
If you mean static variables, then no. Static is per application, and will thus be for all users of your web application, not just one person. Thread static is not a good idea either as a single user may float between threads during his lifetime in the application.

If you have methods that truly do act upon a large number of variables, such as you mention, you can also consider designing a class that has the purpose of acting as a data container. Once populated, you can then pass the class to the functions that require the data instead of ten parameters.
I can not remember the exact example offhand, but in Microsoft's "Framework Design Guidelines" book, they explicitly describe a scenario like your as well as how they have followed the same approach in the .NET Framework.
Also, if you have the need to pass that many parameters, take a step back and make sure that the code in question does not need to be refactored. There are legitimate cases where a lot of data is needed by a method, but I use long method signatures as a sign that I need to look inside the method to make sure it is doing only what it needs to.

Just be sure to be conscious about boxing. If you are passing 10 ref types around, it comes down to personal preference.
However, if you are passing 10 value types, if you were to declare them as member variables within a class, they will be boxed, then they will have to be unboxed by the recipient.
If you leave them confined as local variables within the method stack(passing as parameters), they will remain purely on the stack, rather than being boxed to the heap.

For a purely mechanical refactoring, packaging the values together (as suggested) is probably the best solution.
However, you have a large series of dependent methods, each of which acts on common state (at least 10 values). It sounds like you should design a class to handle this operation.
The class would encapsulate the behavior and relevant state, rather than be a simple property bag (see Anemic Domain Model).

Related

Is it less 'expensive' to pass the field of an object as opposed to the whole object itself?

Consider the following class:
public class Person
{
public String FirstName;
public String LastName;
public DateTime DateOfBirth;
public StaffType PersonType;
}
And the following 2 methods and method calls:
public void DoSomethingWithPersonType(Person person)
{
TestMethod(person.PersonType);
}
(called by DoSomethingWithPersonType(person);)
public void DoSomethingWithPersonType(StaffType personType)
{
TestMethod(personType)
}
(called by DoSomethingPersonType(person.PersonType);).
Which method is more efficient? Are they both as 'efficient' as each other? Does it make no difference because it's only one reference passed in anyway? Or does the reference passed differ in some way?
The reason I ask is because I've opted for the first method signature in a current project - and I've done it because at a later date we may need to use other fields of our 'person' - so a more easily scalable/adaptable method is what I've got - but is it a more expensive one?
EDIT: Note - it goes without saying that these differences will be marginal, otherwise I would've already encountered scenarios were the performance implications are evident enough for me to act on. It's simply a matter of curiosity.
Performance wise they will be identical. In both cases you are passing a single reference (which has the same performance cost) and in both cases you're getting the PersonType object out of one of the fields.
The only difference here is in terms of code readability/maintainability, etc. In general, it's best for methods to only accept what information they need. If you only need a PersonType then only accept a PersonType. It allows that method to be used more flexibly. (What if something other than a Person has a PersonType?) If you think you'll actually need more than just the person type than accepting a Person may be appropriate.
Also note that even if there is a difference here, it would most certainly be tiny. You shouldn't think about every little think in terms of how expensive it is to run. Computers are fast these days. Even poor algorithms tend to take little time to run in practice (from the point of view of a person). If you get to the point where your program is taking longer to run than it needs to, then it's time to start looking for places to improve. You should focus on those areas of the code (identified with a profiler) as being a significant percentage of the processor time. Network communication (including database calls), and other IO tend to be good targets for optimizations.
Also note that it's generally considered bad practice to have public fields. At the very least, you should probably have public properties instead.
Whatever you decide to pass to the method performance implications will depend on context. If you pass parameters between methods in the same class performance implication will be immeasurably small, if you call a method over RMI it is a different matter
That depends somewhat on the type of StaffType, but normally the performance difference is negligible.
If StaffType if a class, then there isn't any difference, as both are references. If it's an enum then it would be marginally faster to pass a StaffType value than a reference.
(If StaffType is a large struct, then it would be slower to pass, but then the actual problem is a badly designed struct, not how you use it.)
So, you should use the one that makes most sense. Usually you should send as little information as possible, just to make it easier to see what the method actually uses. Whether you should send the StaffType value or the entire Person object for future possible expansion is hard to tell, but consider the YAGNI principle - You Ain't Gonna Need It.
Presumably, StaffType is an enum. In this case, it should be marginally more efficient than passing an object reference, the enum will create less work for garbage collection.
But any difference will be negligible, I would rate extensibility as far more important in this case.
Speaking of efficiency, they are equal becuase in both cases you'll pass a reference (speaking of two classes, else if StaffType is a struct the second one will be slower). But in terms of Best Coding Practices, it depends on what do you want to do. If you don't need any other property from the Person class you should use the second one, because you should pass less information as possible, but if you have to work more on the person object, you should use the first solution.
But you have to think to the re-usability of the method and your framework, let's say you need to use this method not only for the Person type but you also need it for another "type" you'll have to rewrite another method for it, and the aim of object oriented programming, which is code less, will disappear.

Static vs non-static class members

I'm new to c sharp and programming generally. I have a quick question - what is best practise with regards to static/non static variables.
I have a variable,private int x, which belongs to class y. To access this variable, i need to reference y. If x was static however, i can access this variable with no references to y.
Which is the best way to go, in a situation whereby several methods within the class y will be referencing this value ?
Hope this makes sense, and my question isn't too basic !
Many thanks
You need to think about static variables as belonging to the class, not to instances of the class.
If, in all instances of the class this variable should be identical, use a static variable.
If not, use an instance variable.
In general having public static variables is bad practice - it is a shared global resource and if you change it you need to synchronize access to it. Having global state is something you want to avoid as much as possible.
Best practice is to avoid public static. In OOP, class is meant to hide its members. Static is actually not a member of the instance but of the type.
Static comes handy if you are implementing singleton pattern. But then again they need to be made private and accessible through a public property.
You need to read Static Classes and Static Class Members (C# Programming Guide).
Well I can't conclusively say that one is better, because they serve different purposes.
Are you familiar with OOP? In OOP, static objects or members of a class that can be accessed directly from the class, while non-static members can only be accessed from the instance it belongs to.
C# follows a similar principle for the methods. The static methods can by accessed directly from the class, while non-static methods (or instance methods as I like to call them) have to be accessed from an instance. That is why instatiating needs to be done for instance methods, while for static methods it's just not needed, and furthermore impractical (see below).
In OOP, static variables are used for values which cannot be stored by an instance variable. Example: supposed you wanted to keep a count of how many instances of a class exists? How would you store that in a single instance?
The methods use a similar principle. They should be used for procedures for which it is impractical to do within an instance of a class. I tend to use them for broad procedures (not a technical term), meaning those that do not require me to instantiate an object. Example, adding two parameters. (This usage may or may not be correct, but I believe it is)
However, if you wanted to add two properties of an object, the method cannot be static, because as you would soon realize, static methods cannot access instance methods or variables within a class. Of course that makes sense because that static method would not know which instance of the class the get these from unless it were told, since it is not part of an instance itself)
For the sake of no further complicating things, I'll stop here. Let me know if you misunderstood anything.
Your choice depends on your architecture.
Static makes part of a Type, others make part of an instance of that type. If you want have some shared state (say) between different instances of the same type, use static. If you want that every instance have it's own value, independent from others, use instance fields.
In both cases, by the way, avoid to expose like a public fields, but use properties.
I completely agree with Mr Oded:
If, in all instances of the class this variable should be identical, use a static variable.
If not, use an instance variable.
Yes, adding static to a class member basically means you can access it without an instance, and only outside any instance. And yes, it becomes a global resource, or even a global variable if you will.
But I think there's at least another (heavily edited) good point to be made here...
Using static members as global vars go against OOP
This means once you set a static member you can't pass it around as an object. The more you use static as global var, the more difficult it is for unit testing / mocking classes.
There is a solution for that, Singletons. But they should never come without warnings!
At other hand, if you're sure you really need global vars, take a look at the Toolbox pattern. It's a not well known extension of Singleton pattern. It's so unknown in fact, if you google for it you won't find it with those keywords (toolbox pattern).
So plan ahead. Read more. Get to know about every option so you can decide better. Even get a book. Object Oriented Programming is more about applying concepts that will help in the long run than just making things work now.
In general if you want to have a variable public, either static or instance, you must wrap it in a property and expose it like that. This is for sure a principle that you will love to follow.
But despite some of the other answers I cannot say don't use static. Static is not the devil that you should avoid in any case. What you have to do will decide if you are going to use static or not, as long as you keep your program clean and easy to maintain.
Easily speaking, and not in the language of the elders, static stands for something that don't belong to any instance of this class but has an effect on them. An example of a static property in a class that generates instances is for example a factor, which should be global for all instances of the class, to take part in a calculation that is done inside instances. To this case, and to my opinion, it is better to have this factor declared as static rather that have it in every single instance. Especially if this factor changes in the lifetime of your program to affect the next calculation.
You need to ask a question to youself: why I need x to be static?
If you make x static it means that x is a part of all objects of class A, but when x is not static it means, than x is a part only of one object.
In geleral using of static fields is painfull for bug tracking, but in some cases this is very helpfull.
I suggest you to look in using of singelton http://en.wikipedia.org/wiki/Singleton

Is it OK to have a class with just properties for refactoring purposes?

I have a method that takes 30 parameters. I took the parameters and put them into one class, so that I could just pass one parameter (the class) into the method. Is it perfectly fine in the case of refactoring to pass in an object that encapsulates all the parameters even if that is all it contains.
That is a great idea. It is typically how data contracts are done in WCF for example.
One advantage of this model is that if you add a new parameter, the consumer of the class doesn't need to change just to add the parameter.
As David Heffernan mentions, it can help self document the code:
FrobRequest frobRequest = new FrobRequest
{
FrobTarget = "Joe",
Url = new Uri("http://example.com"),
Count = 42,
};
FrobResult frobResult = Frob(frobRequest);
While other answers here are correctly point out that passing an instance of a class is better than passing 30 parameters, be aware that a large number of parameters may be a symptom of an underlying issue.
E.g., many times static methods grow in their number of parameters, because they should have been instance methods all along, and you are passing a lot of info that could more easily be maintained in an instance of that class.
Alternatively, look for ways to group the parameters into objects of a higher abstraction level. Dumping a bunch of unrelated parameters into a single class is a last resort IMO.
See How many parameters are too many? for some more ideas on this.
It's a good start. But now that you've got that new class, consider turning your code inside-out. Move the method which takes that class as a parameter into your new class (of course, passing an instance of the original class as the parameter). Now you've got a big method, alone in a class, and it will be easier to tease it apart into smaller, more manageable, testable methods. Some of those methods might move back to the original class, but a fair chunk will probably stay in your new class. You've moved beyond Introduce Parameter Object on to Replace Method with Method Object.
Having a method with thirty parameters is a pretty strong sign that the method is too long and too complicated. Too hard to debug, too hard to test. So you should do something about it, and Introduce Parameter Object is a fine place to start.
Whilst refactoring to a Parameter Object isn't in itself a bad idea it shouldn't be used to hide the problem that a class that needs 30 pieces of data provided from elsewhere could still be something of a code smell. The Introduce Parameter Object refactoring should probably be regarded as a step along the way in a broader refactoring process rather than the end of that procedure.
One of the concerns that it doesn't really address is that of Feature Envy. Does the fact that the class being passed the Parameter Object is so interested in the data of another class not indicate that maybe the methods that operate on that data should be moved to where the data resides? It's really better to identify clusters of methods and data that belong together and group them into classes, thereby increasing encapsulation and making your code more flexible.
After several iterations of splitting off behaviour and the data it operates on into separate units you should find that you no longer have any classes with enormous numbers of dependencies which is always a better end result because it'll make your code more supple.
That is an excellent idea and a very common solution to the problem. Methods with more than 2 or 3 parameters get exponentially harder and harder to understand.
Encapsulating all this in a single class makes for much clearer code. Because your properties have names you can write self-documenting code like this:
params.height = 42;
params.width = 666;
obj.doSomething(params);
Naturally when you have a lot of parameters the alternative based on positional identication is simply horrid.
Yet another benefit is that adding extra parameters to the interface contract can be done without forcing changes at all call sites. However, this is not always as trivial as it seems. If different call sites require different values for the new parameter, then it is harder to hunt them down than with the parameter based approach. In the parameter based approach, adding a new parameter forces a change at each call site to supply the new parameter and you can let the compiler do the work of finding them all.
Martin Fowler calls this Introduce Parameter Object in his book Refactoring. With that citation, few would call it a bad idea.
30 parameters is a mess. I think it's way prettier to have a class with the properties. You could even create multiple "parameter classes" for groups of parameters that fit in the same category.
You could also consider using a structure instead of a class.
But what you're trying to do is very common and a great idea!
It can be reasonable to use a Plain Old Data class whether you're refactoring or not. I'm curious as to why you thought it might not be.
Maybe C# 4.0's optional and named parameters be a good alternative to this?
Anyway, the method you are describing can also be good for abstracting the programs behavior. For example you could have one standard SaveImage(ImageSaveParameters saveParams)-function in an Interface where ImageSaveParameters also is an interface and can have additional parameters depending on the image-format. For example JpegSaveParameters has a Quality-property while PngSaveParameters has a BitDepth-property.
This is how the save save-dialog in Paint.NET does it so it is a very real life example.
As stated before: it is the right step to do, but consider the followings too:
your method might be too complex (you should consider dividing it into more methods, or even turn it into a separate class)
if you create the class for the parameters, make it immutable
if many of the parameters could be null or could have some default value, you might want to use the builder pattern for your class.
So many great answers here. I would like to add my two cents.
Parameter object is a good start. But there is more that could be done. Consider the following (ruby examples):
/1/ Instead of simply grouping all the parameters, see if there can be meaningful grouping of parameters. You might need more than one parameter object.
def display_line(startPoint, endPoint, option1, option2)
might become
def display_line(line, display_options)
/2/ Parameter object may have lesser number of properties than the original number of parameters.
def double_click?(cursor_location1, control1, cursor_location2, control2)
might become
def double_click?(first_click_info, second_click_info)
# MouseClickInfo being the parameter object type
# having cursor_location and control_at_click as properties
Such uses will help you discover possibilities of adding meaningful behavior to these parameter objects. You will find that they shake off their initial Data Class smell sooner to your comfort. :--)

Global variable in a static method

This seems basic but Im finding this quite trivial. Simply how would you recommend setting a global variable with a static class (i.e. console-application)?
To give you a little more background the main method is calling some custom eventhandlers that I hope to get / set the variables.
Any ideas or suggestions you have is appreciated.
Simplest way is
public static Object MyGlobalVariable;
which creates a public static field. A little better is:
public static Object MyGlobalVariable { get; set; }
Which creates a public static property.
There are no global variables in C#. A variable is always locally-scoped. The fundamental unit of code is the class, and within a class you have fields, methods, and properties.
You can mimic a "global variable" by making a public static field or property in some class, but you shouldn't. C# makes this difficult for a very good reason; global variables are pure evil. They violate several good principles of OO design - encapsulation, loose coupling, and high cohesion, to name just a few.
I realize this is a beginner question, but I think it's because this is a beginner question that it's so important to be saying this. Now is the best time to start learning what tactics are actively discouraged or even dangerous in C#, and using a static field/property as a global variable is about six of them. There are legitimate uses for these constructs, but passing data around from place to place is not one of them.
If two different classes depend upon the same information, then pass the information from the source to the destination. This is usually done either through the constructor or as an argument to the method being called. You should always have one and only one instance that truly "owns" this information; making information "global" means that you can't reason about who or what might be depending on it at any given point in time.
Please consider this, and try to think about other ways you could share the information that you want to store in a global variable (i.e. by providing it as an argument to a constructor or method). If you're not sure, post an example of what you're trying to do and we'll help out.
Not 100% sure but you could try a singleton to hold your variables. Without knowing what you are trying to accomplish it's hard to recommend if this solution wouldn't bite you down the road.
http://www.yoda.arachsys.com/csharp/singleton.html

Static methods working on instance fields

I've seen static methods written (but I've never run the code) which uses instance data from another class (instance based).
Usually, instance data work with instance methods and likewise for static fields/methods. What is the implication of working on static data in an instance method? I'm assuming it is frowned upon but I can't find any details on what will happen under the hood. Also, what about instance methods working with static data?
Thanks
There is no problem having a static method use object instances or an instance method using static data.
The framework is full of methods that demonstrates this. The very commonly used String.Concat method for example is a static method that takes one or more object instances. (A Concat method call is what the compiler produces whenever you use the + operator to concatenate strings.)
The Int32.MaxValue is a static property, there is obviously no problem using that in an instance method.
I don't see a problem working on instance data from another object within a static method.
I assume that you mean, for example, passing an object's instance variable to a static method via a parameter, and that method then working on that variable.
Static just means you don't get this, but you could get otherobject->something
I don't think it would be any more frowned upon than just using a static method would be in the first place.
When working with static data in an instance method, the only implication I can think of is synchronization in a multithreaded application. I can't think of any adverse implications when working with instance data from a static method. However, just because something can be done doesn't mean it should be done.
Here is a concrete example you provided.
Class A is instance based and has an
instance field called ProductPrice of
double. Class B is static and has a
static method called
PlayAroundWithPrice(double price), and
the coder passes in the ProductPrice
field.
Obviously, there is nothing technically illegal with this example, but it goes against the grain for me. First of all, the ProductPrice field of Class A is obviously public since Class B can operate on it. For the purposes of encapsulation, I personally always make fields private and use a public property to access them. Second, because ProductPrice is a public field instead of a public property, there's no way for Class A to prevent ProductPrice from being set to invalid values (negative values, for example). Third (as stated above), if this example occurs in a multithreaded program, there could be synchronization issues. Fourth, I guess this is the real rub, why have a static method on Class B to operate on the field of Class A? Why not put the static method on Class A?
I don't know that I'd go as far as making this a hard-and-fast rule (perhaps simply a rule-of-thumb), but I would restrict using static methods for when you do not want to pay for the cost of constructing an object just to use the method.
For example, in the project I work on, I have an IPHeader class that will fully construct an IPHeader instance from a byte buffer. However, in most cases, I only need a couple of values from the IPHeader. So to avoid the costs associated with creating and garbage-collecting an IPHeader instance, I added a couple of static methods that will extract the values from the byte buffer directly.
I hope I've understood your question correctly.
Basically, instance methods has a hidden this parameter which is used to pass the instance the method is supposed to work on. This is the reason static methods cannot access instance data without explicit reference (as they cannot know which instance of object they should access).
Considering this, I don't see any special difference between static and instance methods. They are both methods and has more similarities than differences.
Both static data and instance data are prone to threading issues, however, instances are much less likely to be used between threads. As a consequence, accessing static fields might require more care (regarding syncronization issues).
There should be no problem. Recently I had a scenario where I needed each instance of a class to have a different, but reproducible random seed. I kept a private static int in the class, and incremented it for every instantiation, and used that as the seed.
It worked fine.
I don't think there is anything inherently wrong with using static data in an instance method but I think you need to really limit the types of data you use. The advantage / disadvantage of this approach is that a single data change can alter the behavior of all objects of a particular type. This makes changing that type of data very risky. I tend to constrain uses of this to the following scenarios
Immutable values - Nothing can change so there is nothing to worry about
Global Objects - I strongly refrain from doing this but I've found that occasionally the evils of having a global object outweigh the risks. These objects are carefully monitored though and heavily tested.

Categories