C# static vs instance methods - c#

I'm risking it this might be a newb question but here goes. I'm tempted to add a method to a class that could possible have thousands and thousands of instances in memory at a given time. Now, the other option is creating a static class with a static method, and just create the [static] method there, instead of an instance method in the class. Something like so:
This:
public static class PetOwner
{
public static void RenamePet(Pet pet, string newName)
{
pet.Name = newName;
}
}
Instead of this:
public class Pet
{
public string Name { get; set; }
public void Rename(string newName)
{
this.Name = newName;
}
}
I'm just wondering if the static class alternative would take considerably less memory.
Thanks!

Only data fields require storage per instance, subject to certain conditions and optimisations. For instance, 10,000 instances of a class that define an Int32 member will consume ~40,000 bytes of memory.
Strings, on the other hand, are not so simple due to interning. You can try this as an example:
object.ReferenceEquals("", string.Empty) // returns true!
If the same 10,000 instances also define a string, and that string is the same for each instance, then you're going to have 10,000 references pointing at the same data, reducing overhead considerably (but in a 32-bit environment, there's another 40,000 bytes taken up by the references).
Methods, as pointed out by others, whether static or instance, are only loaded once.
The decision to use either instance or static methods is not influenced by performance reasons, but by how the method is intended to be used. In your case, the method requires an instance of the type as its first parameter so it may as well be an instance method.
Static methods, in my experience, are most useful as an alternative to a type's constructor for returning a new instance. Constructors, once invoked, have to either return a new instance or throw an exception, which may not be desirable. Static methods can return null if something fails, or return a cached instance (the latter of which is useful if the constructor is an expensive operation).

Methods only exist once in memory, regardless if they are static or not, so there is no difference at all in memory usage.

In addition to Guffa's answer:
Methods only exist once in memory,
regardless if they are static or not,
so there is no difference at all in
memory usage.
The instance method has a class instance passed to it as an invisible(which can be explicitly accessed through this) parameter, essentially making the newName of void Rename(string newName) a second parameter passed to your instance method; thus the resulting burned instructions for static void RenamePet(Pet pet, string newName) and void Rename(string newName) look essentially the same, so they has no differences on performance or whatsoever

It doesn't make a difference, methods (static or instance) are only loaded once into memory and JIted, they don't consume more memory just because they are instance methods.

The amount of instances of a class, does not effect how much memory the method uses.

With respect to memory static and instance methods are same except the fact that instance methods can contain data members where as static methods can have only static data members.

In case of memory it doesn't make any difference,Methods exist only once in the memory regardless of being static or instance but static methods are minutely faster to invoke than instance methods because Instance meth­ods actu­ally use the ‘this’ instance pointer as the first para­me­ter, so an instance method will always have that over­head
So static methods have little advantage over instance methods in case of performance but for memory usage they both use same amount.

You don't need a method "Rename" at all; you already have one, it's the setter of the Name property. Instance methods do not require more and more memory on a per instance basis, that would be silly.
Don't make design decisions like this before profiling your code. Adding an instance method to a class is not going to cause a performance bottleneck, and even if it did, you shouldn't start out with a bad design based on a guess; prove it is a bottleneck and make adjustments as necessary.

Related

Why can't we access static method through the object in .net

with the following code:
public class test
{
public static void DoSomething()
{
Console.WriteLine("test");
}
}
public class test2
{
public test2()
{
var a = new test();
a.DoSomething(); // invalid
test.DoSomething(); // is valid
}
}
I need to access the static method through the base class, and not through the instance.
But, what would have been the downside of letting the user access it through the instance? It seems to me that it would help with readability.
You can't call a static method from a class instance, because all static fields and methods are associated with the type rather than an instance of said type.
For a deeper understanding of static classes I suggest you read this.
I guess what you are asking is
When calling a static method, why we must specify the class that
defines the method and when calling an instance method, why we must
specify an instance that refers to the object of that class.
To answer this, we must understand how CLR manages things in the background.
Lets try to understand what happens when a new instance is created:
When we “new” up a class’ instance, the CLR creates an object in the managed heap, this object on the heap (among other things) also contains the bytes necessary to hold all of the instance data fields defined by that class as well as any instance fields defined by any base class (say Object class).
This means the instance fields are tied up with that instance of the class that we just created by newing up in our code.
Now, when calling a static method, the JIT compiler locates the class object that corresponds to the type that defines the static method. Note that it doesn’t uses the instance (object) here. Then, the JIT compiler locates the entry in the class object’s method table that refers to the method being called, JITs the method (if first time called), and calls the JITted code.
Notice the difference in how CLR does the discovery of an instance and static methods.
As for every question on a language-decision you allways have to consider the use and the potential harm that is caused by your request. While it may increase your (personal) readability in a very specific case, it adds lots of confusion to readers of your code that don´t have your source-code. Furthermore it would assume a compiler is able to determine if or if not a member actually does something on the instance or not. So the compiler would have far more complicated logic in order to achieve something you can easily indicate yourself by the static keyword.
In fact an instance-method does something with an instance, it does not neccessarily modifiy its state, it can also just use that state and process some operation. Making something available on that instance-level which does not have instance-semantics seems quite counter-intuituve and breaks the principle of least astonishment - at least for me. If there is a member called on an instance it is supposed to do something with that instance. If or if not this is actually the case is an implementation-detail which a client shouldn´t bother for at all.
Alternatively you can create the static method as an extension method on the base class or the child class. And then you can call it directly from the object instance as you attempted.
Using instance.DoSomething(); would indicate your are calling a method of the instance (which of course would not be true since it is a static class member, not related to the instance iteself). Because of this, it would probably only lead to confusion.
By using MyClass.DoSomething(); it is easily understood that it is in fact a member of the class (not of an instance) you are calling. Perhaps it will be clearer if you follow standard naming conventions (class name with leading capital).
For further understanding of static members, see the Microsoft docs.
I think this is the key line in the documentation:
Only one copy of a static member exists, regardless of how many
instances of the class are created.
Only allowing access through the Class makes sense in light of the above.

When Are Static Classes In .NET Loaded Into Memory?

As the title suggests, I am interested in when static classes are loaded into memory in .NET, C# in particular. I assume it is similar to this question in Java and this question regarding static methods, in that it is loaded the first time it is used. Additionally, once it is in memory does it stay there until the application terminates or does is get cleaned up when the garbage collector comes along to clean up the class that used it?
I realize the small amount of memory a static class uses is not terribly important in a world of computers that have 8+GB of RAM standard, but it is always interesting to know the internals.
Edit:
The answers led me want to add more to this question and to clarify with an example. If I understand correctly, in the example below Contraption.SomeString will be placed in memory first followed closely by Contraption.AnotherString with the first time through the loop.
public static class Contraption
{
public static string SomeString = "Some String";
public static string AnotherString = "Another String";
}
public class Processor
{
public void Process(List<SomeClass> items)
{
foreach(var item in items)
{
if(item.Name == Contraption.SomeString)
{
//do something
}
if(item.Name == Contraption.AnotherString)
{
//do something
}
}
}
}
Regarding static fields initialization, an important point is the usage of static constructor. The CLR has a class loader component, which loads a class (metadata information) and request for memory allocation from the memory manager as they are used in the program. Metadata loading is one time job, post it just request memory on need basis
As understood in the discussion, the static class variables are loaded on the first usage of the class anywhere, and are assigned the memory, but using the static constructor can ensure that they are initialized as the first thing when class loader is invoked, its a one time call, which can do the initialization of all the static variables in a class, this even precede the first usage policy, as its when CLR (mscoree.dll) is components are loaded for a given program.
Static constructor is never called after first time under any circumstance (except program restart), even if there's an exception, its quite widely used, also static variables can be collected by setting them as null
I assume you're referring to fields within static classes (or static fields in non-static classes). They will be initialized before the first use. It's described in the C# specification:
10.4.5.1 Static field initialization
The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration. If a static constructor (Section 10.11) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.
Static class members are considered Garbage Collection roots and all always reachable.
You can force the objects to be reclaimed by resetting the static member to null or other object:
public static class Foo
{
public static object Bar = new object();
}
// somewhere later
Foo.Bar = null;
// the object can be collected now.
Static variables persist for the lifetime of an AppDomain, and in .NET, you can have multiple AppDoamins per application. Although most of the time, it is just one AppDomain per application, and other AppDomains are mostly created for sandboxing plugins.
https://msdn.microsoft.com/en-us/library/2bh4z9hs(v=vs.110).aspx

Calling instance method from a constructor in C#

I have a rather lengthy constructor which is performing various initialisation work, and as such I wanted to factor out some of this work into some functions. This led to me wonder whether I should make the said functions instance or static methods. I understand the risk of calling a virtual function from a constructor but I also think there is something not right about calling an instance method on an object which is not 100% instantiated. Surely this is a contradiction in terms.
I'd be interested in peoples opinion on this matter. I also found that by using a static method to return an initialised variable I could make the member target read-only. Here's a simplified illustration of my scenario.
public class A
{
private readonly string _foo;
public A()
{
_foo = InitialiseFoo();
}
private static InitialiseFoo()
{
// Do stuff
return new string ("foo");
}
}
This is pretty normal to call instance method in a constructor, moreover method which doing Initialization. So basically this is a kind of Extract Method refactorig to reduce a constructor method body, so you are extracting part of initialization into a separate method and constructor is aware on saving of the input arguments, etc...
Regarding the static modifier.. sometimes (I believe when no other ways to refactor because this looks not good - from my point of view) you need to call a method to pass results in a base constructor so in this case you have to mark it as static to call in a static context in other cases leave it without the static modifier
public A()
: base(GetLogger())
{
}
private static ILog GetLogger() ...
I can understand the desire to only use static members in a constructor, because it DOES make the code more straightforward to use without having to track what has been initialized and what hasn't, but you're likely making things needlessly complicated for yourself. Calling an instance method in C# is fine as long as you have a good reason to do it. For instance, if you have a number of constructors that all perform some common tasks, creating a single member function to do the work is easier to maintain than copy-and-pasting the code for each constructor. You can also imagine a case where the method can be re-used outside of the constructor for something like reseting the class to the initialized state.
The static method, is fine, but will only work in the case where you are doing some isolated work and putting the result into a member variable. It provides a very clean, functional programming-like feel. If any of the work involves class state, however, it's going to get ugly.

Should I always make my methods static where possible?

I have often pondered this one... its probably an idiot question but here goes.
Say I have this class:
public class SomeClass
{
public int AProperty { get; set; }
public void SomeMethod()
{
DoStuff(AProperty);
}
}
Is there any advantage to doing this:
public class SomeClass
{
public int AProperty { get; set; }
public static void SomeMethod(int arg)
{
DoStuff(arg);
}
}
The only advantage that is obvious is that I can now access SomeMethod directly.
So is it good practice to make these kind of methods static where a little refactoring will allow or is it a waste of my time?
EDIT: I forgot to mention (and ShellShock's comment reminded me) that the reason I ask is that I use ReSharper and it always makes suggestions that 'Method X can be made static' and so on...
Static isn't evil. Static is evil if used incorrectly, like many parts of our programming toolkit.
Static can be very advantageous. As the accepted answer here points out, static can have a potential speed improvement.
As a general rule if the method isn't using any fields of the class then its a good time to evaluate its function, however ultimately utility methods that can be called without instantiating an object can often be useful. For instance the DirectoryInformation and FileInformation classes contain useful static methods.
Edit
Feel obligated to point out that it does make mocking a lot harder but it is still definitely testable.
It just means you need to think harder about where static methods go, so that you can always test them without needing to rely on a mock/stub. (ie: don't put them on your DTO that requires a persistent connection to the database).
I'll attempt to answer your specific question involving the code sample you provided.
If SomeMethod is only useful in the class it is declared in, I would avoid the static conversion and leave it as an instance method.
If SomeMethod is useful outside of the class it is in, then factor it out of the class. This may be as a static method in a static utility class somewhere. To make it testable, ensure that all its dependencies are passed in to it as arguments. If it has loads of dependencies, you might want to review the design and figure out exactly what it's supposed to be doing - it might be better as an instance method in one of the classes you're passing in to it.
Some people say that static is evil. This is generally because of the pitfalls that mutable static state provides, where variables hang around from the point a static constructor is called to the tear down of an app domain, changing in between. Code reliant on that state can behave unpredictably and testing can become horrendous. However, there is absolutely nothing wrong with a static method which does not reference mutable static state.
For a (very simple) example where a static is evil, but can be converted to a non-evil version, imagine a function that calculates someone's age:
static TimeSpan CalcAge(DateTime dob) { return DateTime.Now - dob; }
Is that testable? The answer is no. It relies on the massively volatile static state that is DateTime.Now. You're not guaranteed the same output for the same input every time. To make it more test friendly:
static TimeSpan CalcAge(DateTime dob, DateTime now) { return now - dob; }
Now all the values the function relies on are passed in, and it's fully testable. The same input will get you the same output.
Static methods make sense, if you should be able to call them without creating an object of the class before. In Java, for example, the Math-Class contains only static methods, because it wouldn't make much sense to instanciate a Math-Class only to do mathematical operations on other objects.
Most of the time it's better to avoid static methods. You should get familiar with object oriented programming - there are lots of good resources out there, explaining all the concepts like static methods, etc.
I think it will depend on the way you want to use the methods. Using a static method is okay if it is used as a common method over a few instances of the class.
For the sake of an example, say you have a string class and two strings A and B. To compare A and B, you can either have a A.CompareTo(B) method or String.Compare(A, B) method.
Please correct me if I am wrong.
No. Static is evil. It tightly couples the caller to the used class and makes it hard to test.

Static methods vs instance methods in C#

For an application I am writing, I want to have extreme extensibility and extension methods seem to give me what I want, plus the ability to call them without an instance, which I need too.
I remember reading that static methods are faster than instance methods but don't get the advantages of GC. Is this correct?
It's highly unlikely I will change my design unless I find a superior alternative by design not speed. But still for extra information I wanna know the differences in speed, GC, etc.
EDIT: Thanks. More info: Let's say we have a Person class:
class Person
which can have an instance Distance method so like:
this.Distance (Person p)
This is great, but this doesn't give me the ability to calculate the distance between 2 points (say Point3), without creating instances of the Person class.
What I want to do is this:
class Person (no Distance methods)
but extension methods of Distance:
Distance (this Person, Person)
Distance (this Point3, Point3)
This way I can both do:
myPerson.Distance (yourPerson)
and
Extensions.Distance (pointA, pointB)
EDIT2: #Jon, yeah I think that was what was meant by (don't get the advantages of GC), but I somehow thought that the static methods create this burden/overhead.
Choosing between static and instance methods is a matter of object-oriented design. If the method you are writing is a behavior of a an object, then it should be an instance method. If it doesn't depend on an instance of an object, it should be static.
Basically, static methods belong to a type while instance methods belong to instances of a type.
What do you mean by "don't get the advantages of GC"? Methods aren't garbage collected - instances are.
Virtual methods are slightly slower than non-virtual ones, and I guess there's that pesky null check before any instance method, but it's not significant. Go with the most appropriate design.
Static methods are a pain for testing though - for instance, if you authenticate in method Foo() by calling some static method, then when you're testing Foo() you can't make it just call a mock authenticator (unless the static method itself lets you do that). If you give the original instance of whatever you're testing a mock implementation of some interface containing an Authenticate() method, however, you can make it behave however you want.
EDIT: In this case, it sounds like what you really need is an instance method on your Point type to calculate the distance between two points ("this" one and another) - or potentially a static factory method on the Distance type.
If by being faster you mean the code inside the method is executed faster, then no. A code in a static method is just as fast as code in a non static method.
If your are talking about the overhead of performing the call to the method it becomes a little more complex. It is common for languages as Java that instance calls have more overhead. In C# this is not the case however because instance methods are not virtual by default.
So a virtual method has slightly more overhead than a non virtual method. Static methods cannot be virtual, but instance methods can be declared virtual.
As for Garbage collection, this is mainly relevant for fields, not methods. Static fields can be accessed from everywhere in the code so the garbage collector can't determine if the reference will be used again, so it is never collected.
Based on your example, I would write a static utility function to find the distance between two points:
public static class Geometry
{
public static double GetDistanceBetween(Point a, Point b) { ... }
}
And then I would give Person a property called Position that returned a point. So I could write:
double distance = Geometry.GetDistanceBetween(personA.Position, personB.Position);
It's practically in English already - why make it more obscure? If you make Distance a method, then you can write:
personA.Distance(personB)
or:
personB.Distance(personA)
There's no difference between those two orderings, and yet the use of method-call syntax suggests that there might be a difference.

Categories

Resources