dharmatech
dharmatech

Reputation: 9527

C# classes - Why so many static methods?

I'm pretty new to C# so bear with me.

One of the first things I noticed about C# is that many of the classes are static method heavy. For example...

Why is it:

Array.ForEach(arr, proc)

instead of:

arr.ForEach(proc)

And why is it:

Array.Sort(arr)

instead of:

arr.Sort()

Feel free to point me to some FAQ on the net. If a detailed answer is in some book somewhere, I'd welcome a pointer to that as well. I'm looking for the definitive answer on this, but your speculation is welcome.

Upvotes: 20

Views: 1196

Answers (6)

Bill K
Bill K

Reputation: 62789

Perceived functionality.

"Utility" functions are unlike much of the functionality OO is meant to target.

Think about the case with collections, I/O, math and just about all utility.

With OO you generally model your domain. None of those things really fit in your domain--it's not like you are coding and go "Oh, we need to order a new hashtable, ours is getting full". Utility stuff often just doesn't fit.

We get pretty close, but it's still not very OO to pass around collections (where is your business logic? where do you put the methods that manipulate your collection and that other little piece or two of data you are always passing around with it?)

Same with numbers and math. It's kind of tough to have Integer.sqrt() and Long.sqrt() and Float.sqrt()--it just doesn't make sense, nor does "new Math().sqrt()". There are a lot of areas it just doesn't model well. If you are looking for mathematical modeling then OO may not be your best bet. (I made a pretty complete "Complex" and "Matrix" class in Java and made them fairly OO, but making them really taught me some of the limits of OO and Java--I ended up "Using" the classes from Groovy mostly)

I've never seen anything anywhere NEAR as good as OO for modeling your business logic, being able to demonstrate the connections between code and managing your relationship between data and code though.

So we fall back on a different model when it makes more sense to do so.

Upvotes: 2

Daniel
Daniel

Reputation: 47914

Assuming this answer is correct, instance methods require additional space in a "method table." Making array methods static may have been an early space-saving decision.

This, along with avoiding the this pointer check that Amitd references, could provide significant performance gains for something as ubiquitous as arrays.

Upvotes: 8

Amitd
Amitd

Reputation: 4859

Also see this rule from FXCOP

CA1822: Mark members as static

Rule Description

Members that do not access instance data or call instance methods can be marked as static (Shared in Visual Basic). After you mark the methods as static, the compiler will emit nonvirtual call sites to these members. Emitting nonvirtual call sites will prevent a check at runtime for each call that makes sure that the current object pointer is non-null. This can achieve a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue.

Upvotes: 6

Chris Moschini
Chris Moschini

Reputation: 37967

The classic motivations against static:

  1. Hard to test
  2. Not thread-safe
  3. Increases code size in memory

1) C# has several tools available that make testing static methods relatively easy. A comparison of C# mocking tools, some of which support static mocking: https://stackoverflow.com/questions/64242/rhino-mocks-typemock-moq-or-nmock-which-one-do-you-use-and-why

2) There are well-known, performant ways to do static object creation/logic without losing thread safety in C#. For example implementing the Singleton pattern with a static class in C# (you can jump to the fifth method if the inadequate options bore you): http://www.yoda.arachsys.com/csharp/singleton.html

3) As @K-ballo mentions, every method contributes to code size in memory in C#, rather than instance methods getting special treatment.

That said, the 2 specific examples you pointed out are just a problem of legacy code support for the static Array class before generics and some other code sugar was introduced back in C# 1.0 days, as @Inerdia said. I tried to answer assuming you had more code you were referring to, possibly including outside libraries.

Upvotes: 1

millimoose
millimoose

Reputation: 39980

The Array class isn't generic and can't be made fully generic because this would break backwards compatibility. There's some sort of magic going on where arrays implement IList<T>, but that's only for single-dimension arrays with a lower bound of 0 – "list-ish" arrays.

I'm guessing the static methods are the only way to add generic methods that work over any shape of array regardless of whether it qualifies for the above-mentioned compiler magic.

Upvotes: 0

K-ballo
K-ballo

Reputation: 81389

Because those are utility classes. The class construction is just a way to group them together, considering there are no free functions in C#.

Upvotes: 11

Related Questions