How to structure classes in a C# program - c#

I have a VSTO (Excel) project written in C#. Three questions:
I have a lot of variables that are populated once and then referenced extensively throughout the project. So I created a public static class which I called "Omni" - since that is both descriptive and short. Is something like this the recommended approach?
I put common functions in a public static class that I named "Utilities". I then used the "this" keyword as the first parameter, making them extension methods. They can then be accessed from anywhere - without using a "Utilities." prefix (although I'm not exactly sure why). Same question: is this the preferred way of doing this?
Finally, I have some common 'subroutines', i.e., public void methods. So parameters are passed in and processed, but nothing is returned. Should such common code just go in its own appropriately named public static class and then get called with the class name as a prefix? If so, is there any convention as to what the name of the class would be?
I realize these are newbie type questions (and I have been searching for a while!). Thanks.

Regarding your points
I have a lot of variables that are populated once and then referenced
extensively throughout the project. So I created a public static class
which I called "Omni" - since that is both descriptive and short. Is
something like this the recommended approach?
Yes, it is common practise to centralize for example string constants that
are often used.
If you have more of those, I would start to structure those to different
classes.
If you want that to be flexible and e.g. have cases where there are
mappings between constants, like Green = 1, I would move to some
enumeration value technology.
More on that idea can be found in this article
If the value does not change between different starts of your application,
check if you can use resources for that, which is often a good choice
for string constants to.
I put common functions in a public static class that I named
"Utilities". I then used the "this" keyword as the first parameter,
making them extension methods. They can then be accessed from
anywhere - without using a "Utilities." prefix (although I'm not
exactly sure why). Same question: is this the preferred way of doing
this?
Extension methods are a handy way of getting things like conversions done.
Just do not everything as an extension, just conversions as a rule of thumb.
Finally, I have some common 'subroutines', i.e., public void methods.
So parameters are passed in and processed, but nothing is returned.
Should such common code just go in its own appropriately named public
static class and then get called with the class name as a prefix? If
so, is there any convention as to what the name of the class would be?
This, in opposite of the others, looks like a design flaw.
Perhaps you can provide more information on what those subroutines do.
In object oriented code, code is distributed near the objects it is working
with. If you depend heavily on code that is in static classes, probably there
is something wrong. Do your static classes have members? Do they share some
knowledge between different calls to your static classes?

Related

What are the desirable situation (real life example) to create static methods except for creating helper?

I just want to understand the purpose that static method serves and what are the desirable situation where i can create static methods except some would say that static methods are used for creating helper.
Consider i have 1 website that will be used in my company only like Human resource management system like websites.
Now after Admin login in to the system admin will see the list of employees.so the method is simple which does nothing more than fetching all details of employees from employee table and will display them on the web site and this method will be define in business access layer like this in .net:
public class EmployeeBal
{
public List<Employee> GetAllEmployees()
{
return Select * from Employee
}
}
This is how i would call this method from my application.For Eg(.aspx page or mvc controller etc....)
var employeeBal= new EmployeeBal();
employeeBal.GetAllEmployees();
So my question is should i create this method as static method or non static method??
Note:This is just an example of method and this method is in my business access layer.
Consider i have 1 ecommerce website where on the home page i am displaying some list of products and on visit of that website every users can see that list of products.
so my function would be same as above define in Business acess layer:
public class ProductBal
{
public List<Product> DisplayProductonHomePage()
{
return Select * from Products
}
}
So my question would be same like whether to create this method as static method or non-static method and what will happen if more than 10 users at same time simultaneously access this website then what will be the behaviour/implications of this method???
Will this method will serve the purpose of this each user if we declare this method as static??
Can anybody answer this question with briefly explaining every scenario???
A static method makes sense when there’s no state to maintain. What do I mean by state? Well, consider the following: You have two distinct objects, a and b, which are both of type EmployeeBal. Is there ever a case in your program where a.GetAllEmployees() and b.GetAllEmployees() would yield different results?
If not, then why do the objects a and b exist at all? The whole point of having objects is to associate some distinct state with them. If two different objects can never refer to a different state, then they fulfil no purpose.
In fact, in this situation your EmployeeBal would be exactly equivalent to System.Math, and all its methods are “helper methods” (if that’s what you want to call them). In this case, forget about static methods for a minute: your whole class should be static (static class EmployeeBal), and it should not have any constructors; because the concept of an object of type EmployeeBal simply makes no sense. In fact, in other languages EmployeeBal wouldn’t be a class at all; instead, it would be something generally called a module: a unit that logically groups code. C# has no modules, and all code must reside within classes. Classes thus fulfil a dual purpose: they group code, and they generate objects.1
Now consider a less extreme case: EmployeeBal objects actually maintain state, and differ. Yet GetAllEmployees() will still yield the same result, regardless of which object calls the method.
In this case, EmployeeBal obviously cannot be a static class. But GetAllEmployees is still stateless, and thus doesn’t belong to objects of type EmployeeBal. And thus the method should be static.
1 This lack of distinction between two fundamentally distinct concepts (module and class) is actually quite annoying, and the main reason that C# behaves this way is because it was conceived to be similar to Java. It was a mistake in hindsight, but not a serious one.
Is there a reason why the method should be static? If not I'd always side with non-static.
One big reason is being able to write unit tests.
In order to write unit tests you want to be able to isolate the class you're testing from other classes. But if class A contains a reference to static class B, then you can't test A without testing B. Maybe B depends on connection strings or config settings. Maybe B depends on other static classes. Now you can't test A unless B and everything it depends on are in place.
If, on the other hand, class A depends on an interface like IEmployeeProvider that gets provided through its constructor then you can test class A with a mocked implementation of IEmployeeProvider.
If A has IEmployeeProvider as an argument in its constructor then you can tell by looking at the constructor that it depends on IEmployeeProvider. But if it depends on a static EmployeeProvider class somewhere inside a method then the dependency is hidden. You have to read the whole class to know what it depends on.
Also, the static class itself can be harder to test. Unless it's absolutely always going to remain stateless then it's better to have a non-static class that you can unit test.
It's fine to have multiple threads executing the same static method, as long as the method does not access static state such as field or properties. In that case, the shared objects stored in the fields/properties must themselves be thread safe. The data access parts of .Net are not designed to be thread safe.
As soon as you start considering aspects such as managing a database connection that can be reused for several queries during the execution of a single web request, you should consider if static is the best approach. Since you cannot store the connection in a static field as explained above, you will have to pass it as a parameter to each static method. On the other hand, if you pass the connection to a constructor and store it in a (non-static) field, you can access it from multiple non-static methods of that instance, which will IMO be easier to manage.
This is quite a big topic however, and in general the management of class dependencies is quite tricky to get right in OOP. Some programmers prefer to delegate this task to an "Inversion of Control"-library. There are many available for .Net such as Microsoft Unity, StructureMap, AutoFac, etc.
To answer your question:
So my question is should i create this method as static method or non static method??
Note:This is just an example of method and this method is in my business access layer.
I would make those methods static - given what you provided. But I bet that you would have instance variables either declared in your class, or in methods in that class, which then of course that would mean don't make it static.
So a determining factor for me if I decide to use a static method or not has to do with re-use and resources.
If I find myself re-using a method many times over, and I conclude it doesn't need state (kept in memory) - I will make it a static method.
Also I usually will make my methods static if they can be used in other applications or if I think they will be useful down the road.
For example I recently wrote a method that converts a excel file to a flat file. I made this a static method in its own static class (i may put it in a similar utility class down the road) because I will probably end up using it again in another project, so I can now just reference its class without having to instantiate a new object to just call the method. ( I don't need state anyways)
I'm pretty new to programming as well and I hope you found this helpful.
If we are going to talk about static, we need to introduce a dependency. In this case it is a sql client. Here's what the code looks like with that introduced. Since we aren't going to get into the details of a sql client it's used as an interface in the static method.
var client = new SqlClient();
var allEmployeeData = EmployeeBal.GetAllEmployees(client);
class EmployeeBal
{
public static Employee GetAllEmployees(ISqlClient client)
{
return client.Execute("Select * from Employee");
}
}
Dependency injection through an interface changes everything. Now the method is good as being static, because it only deals with an interface and a string. Both of these are stateless. Since all components of the method are stateless they are perfectly safe for a static method which can have only one global state.
As your code was written originally it's not safe as being static, because how can I be assured the sql client is prepared to be used and after I've checked that it's ready it hasn't been altered when I go to run the query? If I can inject the sql client I can manage it since it has a local vs global scope.
A better example would be something like a factory for a sql client. For example with nhibernate there should only be one session factory created. That one thread safe session factory can create multiple non-thread safe sessions for running sql queries. In this case it's appropriate to have the session factory exposed through a static method, because that describes the fact that there is only ever going to be one session factory.
var session = SessionFactory.OpenSession();
Using static methods is equivalent of having a global behaviour. It comes with benefits: ease of access for simple scenarios.
It also comes with all the problems that global data and state have. Among them you cannot substitute an implementation with another (for example for tests). See https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil
While you might consider that you don't have a global state ... conceptually you have. You have a unique, predetermined, unconfigurable, hard coded way of accessing some behaviour. You published it and you cannot change it ... ever. You break the open-close principle. You break the liskov substitution principle.
Java has this but scala amended that. More on this here: Why doesn't Scala have static members inside a class?
Use cases for static and non-static methods differ, so you need to create one based on what's the need that they fulfill:
Static method does not participate in inheritance-based polymorphism, while non-static does. In other words, you can't mark static method as virtual or abstract, which means you cannot change its behavior. This also means that caller of the static method knows exactly what this static method is going to do and how exactly. With non-static method, you can be calling it on base class but due to polymorphism you may end up calling the derived class method with overriden behavior.
Both static and non-static methods can be changing a state of something (as opposed to what others claim), but there's a difference. You can design a static class that has all static members (properties, methods, etc.) in it, so the methods can be changing the state of this static class (that said, even though C# allows you doing that, I don't recommend creating such class anyway). With non-static method, you can be changing both static and non-static state of the class. This goes further into the differences between static and non-static classes, which in short means: static class is one concrete instance, while a non-static class can be multiplied and each of them will have its own copy of the state (so why design a static class with the artificial limitation then - this is why I didn't recommend them before).
One more nice usage of static methods is extension methods. These should be defined as static, but you can call them on the instance of the class that they are extending. They still serve as outside shortcuts to the instance, since they can't do anything more than regular static methods (cannot access private or protected members for instance).
And you're right, static class fits well when defining helper methods, because those usually are just shortcuts to some fixed functionality, accessible easily to re-execute it from many places. In Visual Basic, instead of static keyword you would use shared keyword, which nicely explains the purpose of the static method.
Finally, I personally recommend creating static methods as Pure functions, which always produce same output for the same input (no side effects, such as output is different based on time or other implicit factors). You should have a strong reason to design it otherwise (e.g. if you are writing Math.Random()).
Now, to answer the points from your question (I know, finally):
I think business access layer should not be static, because you would most likely need benefits of non-static classes, such as dependency injection and unit-testability.
There is no difference between static and non-static methods from the threading/multithreading standpoint, both of them can be called by multiple threads at the same time and all of them will execute simultaneously (unless using synchronization constructs). However, there is common design recommendation that you should make static methods thread-safe if you expect race conditions. Non-static methods don't have to worry about this, as this would put them into too many assumptions.

Reusable Class Library Implementation

I've built a reusable Class Library to encapsulate my Authentication logic. I want to be able to reuse the compiled *.dll across multiple projects.
What I've got works. But, something about how I'm making the reference, or how my Class Library is structured isn't quite right. And I need your help to figure out what I'm doing-wrong/not-understanding...
I've got a Class Library (Authentication.dll) which is structured like this:
namespace AUTHENTICATION
{
public static class authentication
{
public static Boolean Authenticate(long UserID, long AppID) {...}
//...More Static Methods...//
}
}
In my dependent project I've added a reference to Authentication.dll, and I've added a using directive...
using AUTHENTICATION;
With this structure I can call my Authenticate method, from my dependent project, like so...
authentication.Authenticate(1,1)
I'd like to be able to not have to include that "authentication." before all calls to methods from this Class Library. Is that possible? If so, what changes do I need to make to my Class Library, or how I'm implementing it in my dependent project?
In C# a function cannot exist without a class. So you always need to define something for it, being a class for a static method or an object for an object method.
The only option to achieve that would be to declare a base class in the Authentication assembly from which you inherit in the dependent projects.
You could expose Authenticate as a protected method (or public works too), and call it without specifying the class name.
public class MyClassInDependentProject : authentication
{
public void DoSomething(int userId, long appId)
{
var success = Authenticate(userId, appId);
…
}
}
That said, you'll quickly find this to be a bad design. It conflates a cross-cutting concern with all sorts of other classes, and those classes are now precluded from inheriting from any other class.
Composition is a core principle of object-oriented programming, and we have the idiom "Favor composition over inheritance." This simply means that we break down complexity into manageable chunks (classes, which become instantiated as objects), and then compose those objects together to handle complex processing. So, you have encapsulated some aspect of authentication in your class, and you provide that to other classes compositionally so they can use it for authentication. Thinking about it as an object with which you can do something helps, conceptually.
As an analogy, think about needing to drill a hole in the top of your desk. You bring a drill (object) into your office (class). At that point, it wouldn't make sense to simply say "On," because "On" could be handled by your fan, your lamp, your PC, etc. (other objects in your class). You need to specify, "Drill On."
If you are making a class library in C# you should learn to use the naming conventions that exists: Design Guidelines for Developing Class Libraries
Here is how you should name namespaces: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/interface
C# is also an object oriented language, hence the need of classes (using Authentication as you should name your class).
It also seems like the data source is hard coded. Your class library users (even if it's just you) might want to configure the data source.
Google about singleton and why it's considered to be an anti pattern today (in most cases).
You are obliged to use Class in order to invoke your method, just
When is static class just NameClass.Method
When is not static, you must create instance, ClassName ob = new ClassName(); ob.Method();
The format of a call like this is class.method, and you really can't escape using the "class" moniker even with the "using" designation. Something has to "host" the function.
I don't think what you are asking for is possible without using the base class method Jay mentioned. If all you want is to simplify the syntax whenever you call Authenticate() however, this silly solution (adding an extra method in each class that needs to do authentication) may be just what you want:
private static void DoAuth(long UserID, long AppID){
authentication.Authenticate(UserID, AppID)
}
If the ID's are always the same within some context, you could also overload it:
private static void DoAuth(){
DoAuth(1,1)
}
Yes, this does mean you have to add more code wherever you want to do the authentication (that's why it's silly! ;) ). It does also however, also reduce this:
authentication.Authenticate(1,1);
...into this:
DoAuth();
I leave the cost / benefit analysis of this up to you..
I know I am some 3 years late but here goes nothing.
To keep your code cleaner and more readable you should create a new namespace for all the re-usable code that you want to have. Then in that namespace have the Authentication Class and Authenticate Function.
To use this you can easily set a using on your namespace and use the function as you are doing like
Authentication.Authenticate()
But to use
Authenticate()
by itself you can always do
using MyNamespace.Authentication;
and in your code use Authenticate Function directly.

Should I use (otherwise optimal) class names that conflict with the .NET BCL's names?

This situation probably is not entirely uncommon to some of you: you have some functionality to put in a class but the perfect name (*) for that class is taken by one of the classes in the System namespace or other namespace/class that's not yours but you're using/importing.
(*) By perfect I mean small, concise and clear names.
For instance I have an Utils class that has a Diagnostics (mostly debug utils) class and a Drawing class. I could:
have a DrawingUtils class and a DiagnosticsUtils class, but that just smells like bad structure.
pick a thesaurus and be done with an worse, longer or awkward name that's casually still not taken.
Write class names in my native language instead of English.
Ask the smart guys at StackOverflow.
I think options 1-3 aren't promising :(
EDIT:
Since my chosen answer doesn't address the problem definitively (neither I do), what I'd recommend for people facing the same situation is to ask yourselves: Will you frequently use the conflicting BCL class/namespace? If no, then let your name conflict (as I did with Diagnostics). If yes, add a word that limits the possibilities of your class/namespace.
In practice, this means:
"Drawing": Something that draws.
"MyCustomControlDrawing": Something that draws only on MyCustomControl. e.g.: "WidgetDrawing".
EDIT2:
Another solution to take a look next time: Extension Methods (courtesy of Lawnmower).
I don't see any issue with keeping the names Drawing, Diagnostics etc. That's one of the purposes of namespaces, to resolve naming conflicts.
The beauty of namespaces is that they allow you to create classes with identical names. You can assign an alias to a namespace when you import it into your file with a using statement.
using MyAlias = My.Custom.Namespace;
this will keep your classes separate from Microsoft's.
you can then reference your classes as
MyAlias.Diagnostics
or you could alternatively assign an alias to Microsoft's namespace, but I wouldn't recommend this because it would confuse other developers.
To me, it really isn't worth the hassle of purposefully writing conflicting class names. You'll confuse other developers who aren't familiar with your codebase, because they will be expecting to use BCL classes but end up with yours instead (or vice versa). Then, you just waste their time when they have to write specific using aliases.
Honestly, coming up meaningful identifier names is a useful skill, but it isn't worth delaying your development. If you can't come up with something good quickly, settle for something mediocre and move on. There is little value in toiling over the names. I dare say there are more productive things you could be doing.
EDIT: I also don't believe that "small" is a component of a "perfect" identifier. Concise and clear, for sure, but if it takes a longer name to convey the purpose of a particular construct, so be it. We have intellisense, after all.
Use namespaces to disambiguate your classes from the classes in other namespaces. Either use fully qualified names or a using statement that tells the compile what you need:
using Type = MyReallyCoolCustomReflector.Type;
Now if you want to still use the Type class from the System namespace:
System.Type sysType = anObject.GetType();
Generally I try to avoid name duplicates but this doesn't always work out that way. I also like simple, readable and maintainable code. So as often it is a trade-off decision.
Well, if you want to avoid a namespace collision there are a couple of things you can do:
Don't collide, instead choose a unique name.
Example:
If you are creating a Math class you can name yours CamiloMartin.MathHelper
Use the long namespace to distinguish between collissions.
Example:
public class MyClass
{
public int SomeCalculation(int a, int b)
{
return MyNamespace.Math.SomeFunc(a, b);
}
}
Using an alias to differentiate.
Example:
using System.Math;
using SuperMath = MyNamespace.Math;
namespace MyNamespace
{
public class MyClass
{
public int SomeCalc(int a, int b)
{
int result = Math.abs(a);
result = SuperMath::SomeFunc(a, b);
return result;
}
}
}
Just for the record: .NET framework doesn't have neither Utils nor Diagnostics class. (But does have System.Diagnostics namespace.)
Personally I don't like general-purpose classes like Utils because their methods are not very discoverable (and usually either too general or too specific), therefore I would justify their use only as for internal classes.
As for the rest -- I agree with others on that namespaces are convenient. (Although I would thought twice to name the class if there is already a class in System with the same name, not because of name conflicts, but rather because the reason why I can't use 'original' class could mean that the class I'm about to create is semantically different.)
Often its possible to choose a more specific name. Take Utils for example. Absolutely everything can be called a utilitiy. For the reader of your code this classname is worthless.
Often utility classes are a collection of methods that didn't really fit anywhere else. Try to place them where they belong, or group them by some criteria, then use the group as a classname. Such grouping is in my experience always possible.
In general:
That's what we are doing (hey, we can refactor it later)
Used it once or twice but only on important classes. Especially useful if you don't know the 'perfect' name yet.
don't even think about this...
Using namespace aliases is no fun. So I avoid it if I can.

Best Practices on Code Duplication c#

I am trying to structure my code in such a way to reduce/avoid code duplication and I have encountered an interesting problem. Every time my code invokes a stored proc, I need to pass few variables that are common to the stored proc: such as username, domain, server_ip and client_ip. These all come from either HttpRequest object or a system.environment object.
Since these are passed to every stored proc, my initial thought was to create a utility class that is a database wrapper and will initialize and pass these every time, so I don't have to do it in my code.
The problem is though that c# class (inside App_Code folder) doesn't see Httprequest object. Of course, I could pass this as an argument to the wrapper, but that would defeat the whole purpose of creating the wrapper. Am I missing something here?
I realize it's not such a huge deal to repeat 4 lines of code each time I call a stored proc, but I would rather eliminate the code duplication at the very early stages.
Set up your data layer to inherit from a base class which contains 4 properties for those values. Make the public constructor require those 4 properties.
Then do something similar in the business layer - base class with those 4 properties in the constructor.
Then the UI does new BusObj( Request["username"], ... ).method()
Within the data layer you can have a method that builds a SQLParameter array with those 4 properties, then each method can add additional parameters to the array.
As a general rule regardless of programming language, if you can squint your eyes and the code looks the same you should make a function/method/message out of it and pass the parameters.
Another thing to look at once you have methods that take a large number of parameters (4 is a good rule of thumb, but it is definatly a case-by-case basis) it is time to make that method take an object as a parameter instead of individual parameters. 99.99999999999999999999% of the time such an object should be immutable (no writeable instance variables).
HttpContext.Current has similar information to what you find in HttpRequest and more importantly is available inside App_Code.
Here's a weird idea you may or may not like: define a 'profile' class and a function that expands the profile into the arguments of functions taking the common arguments.
class P {
readonly string name;
readonly string domain;
public P(string name, string domain) {
this.name = name; this.domain = domain;
}
public void inject(Action<string, string> f) {
f(p.arg1, p.arg2);
}
public T inject<T>(Func<string, string, T> f) {
return f(p.arg1, p.arg2);
}
}
It might work better in VB.net where you have the AddressOf operator. I would be really cautious using this type of thing, because you could easily damage readability and encapsulation.
I would keep it the way you have it now. It's cleaner, easier to extend/modify, and easier to unit test.
As for using HttpContext instead as some others have suggested, I would say that it is a bad idea. Once you start introduce dependencies in your domain on HttpContext, it's very difficult to take it out. What if later on you wanted to use your module without an HttpContext? What about unit testing it?
Try System.Web.HttpContext.Current.Request to get the current request.
You are possibly headed down a slippery slope. The point to DRY is to not repeat business logic in multiple places where a change in requirement creates the need to change code in multiple similar places. You don't necessarily refactor just because 4 lines are the same if those 4 lines are context dependent. You have also broken encapsulation by referencing the httprequest in that you are using a global variable. As a consumer of you class I would have to know the implementation detail that I could only call you from a web application.
That being said, if you take that into account and still want to proceed, here is another option for information like this. Create a custom SecurityPrincipal (Implement IPrincipal) that contains the properties you need and attach it to the thread. Fill them when the user logs in and then you can access it anywhere during the request. Your caller would still need to make sure this was done but at least it isn't platform specific.
Otherwise for the best encapsulation, pass in a class with the properties you need into the constructor for each object that needs to consume those properties.

Regarding Passing Many Parameters

I have around 8-9 parameters to pass in a function which returns an array. I would like to know that its better to pass those parameters directly in the function or pass an array instead? Which will be a better way and why?
If I would do anything, then it would be to create an structure that holds all parameters to get nice intellisence and strong names.
public struct user
{
public string FirstName;
public string LastName;
public string zilionotherproperties;
public bool SearchByLastNameOnly;
}
public user[] GetUserData(user usr)
{
//search for users using passed data and return an array of users.
}
Pass them individually, because:
that is the type-safe way.
IntelliSense will pick it up in Visual Studio and when you write your calling functions, you will know what's what.
It is faster to execute that way.
If the parameter really IS the array, though, then pass the array. Example:
For functions which look like this, use this notation:
Array FireEmployee(string first, string middle, string last, int id) {...}
For functions that look like this, use the array:
Array FireEmployees(Employee[] unionWorkers) {...}
Your scenario is covered by the Introduce Parameter Object refactoring in Martin Fowler's refactoring book. The book is well worth owning, but for those who don't, the refactoring is described here. There's also a preview on the publisher's site, and on Google books. It recommends replacing the parameters not with an array, but a new object.
Regarding Skeets comment on my example above that he would use a class instead of a structure and maybe make it clearer where to use a class and where to use a structure i post this too. I think there are other out there who are curious about this too.
The main reason to use a class as I could see was you could make it immutable, but thats possible with structures too?
for example:
struct user
{
public user(string Username, string LastName)
{
_username = Username;
}
private string _username;
public string UserName {
get { return _username; }
}
}
I have long time felt that I dont know the differences anymore between classes and structures now when we can have propertys, initializers, fields and exactly everything that a class has in a structure too. I know classes are refernce types and structures are value types but what difference does it make in the case above when using it as a parameter in a function?
I found this description of the differences on the site http://www.startvbdotnet.com/oop/structure.aspx and that description is exactly how I mapped it in my head:
Structures can be defined as a tool
for handling a group of logically
related data items. They are
user-defined and provide a method for
packing together data of different
types. Structures are very similar to
Classes. Like Classes, they too can
contain members such as fields and
methods. The main difference between
classes and structures is, classes are
reference types and structures are
value types. In practical terms,
structures are used for smaller
lightweight objects that do not
persist for long and classes are used
for larger objects that are expected
to exist in memory for long periods.
Maybe this should be a own question but I felt it was related when we all had different views on the structure vs class-thing as parameter.
I assume you're using C# 4 and can just use named parameters:
FireEmployee(
first: "Frank",
middle: "",
last: "Krueger",
id: 338);
These make the code almost as readable as VB or Smalltalk. :-)
If not, I would go with what Dave Markle has to say.
If this is library code that will see a lot of use, and if some of the parameters have typical values that are candidates for default values, then you should consider Dave Markle's advice, and provide a selectio of overloads with progressively fewer parameters. This is the approach recommended in the Microsoft Framework Design Guidelines.
Alternately, you can get a similar effect with Stefan's approach, by setting default values with member initializers and using a progression of ctor overloads.
If you really don't want to pass in your arguments separately I would suggest creating a new class which encapsulates all of your arguments. You can (in Java and most likely in C#) declare a public inner class inside the class containing the gnarly method for this purpose. This avoids having classes floating around which are really just helper types.
I would say pass them individually as well. I don't like the idea of creating a class, then passing that class through as an argument. Its a form of stamp coupling, which means making changes will be harder since one class uses the other. And reusing one class means you would have to reuse the other as well.
You could use an interface to reduce stamp coupling, but that's too much overhead for my tastes, so that's why I like to pass the arguments individually.
Do you really need 8-9 parameters for a single function? It seems to me that if you need that many parameters, then you're probably doing too many different things in that function. Try refactoring the code into separate functions so that each function has exactly one purpose.
Do not pass them as an array unless the function acts on an array, I wouldn't create a new data structure either to group the parameters for the following reasones
Passing a new data structure hides what the function really needs as input (does it need all the data structure/part of it?)
Related to 1 it makes UTs more difficult (when writing a UT you need to recreate the entire data structure)
If the input parameters are not related you end up with a new data structure that groups unrelated data types for no other reason than to make a function call look neater
If you chose to pass the new data structure to your function the function can not be used in a scope where the new datastructure was defined
Really the only disadvantage to passing each paramater to the function is that you might not be able to fit the function in one line of code, but don't forget the lines you need before the function call in which you will fill up your data structure.

Categories