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.
Related
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.
I need to know how to prevent a class from being Instantiated in .net?
I know few methods like making the class Abstract and Static.
Is there any more way to achieve this?
Making the class static is the best approach, if you absolutely don't want any instances. This stops anyone from creating instances. The class will be both sealed and abstract, and won't have any constructors.
Additionally, the language will notice that it's a static class and stop you from using it in various places which imply instances, e.g. type arguments and variables. This indicates the intention more clearly than just having a private constructor - which could mean that there are instances, created within that class (e.g. for a singleton implementation).
Oh, and making the class static will stop you from introducing any pointless instance members in the class, too :)
See MSDN for more information about static classes.
Mark the constructor(s) private, protected or if in used from another assembly, internal
Marking the constructor private. Of course, this doesn't prevent the class from instantiating itself through a static method, for example...
More practically, what's the purpose of disallowing class instantiation. If it's to have a singleton, then a private constructor is appropriate. If it's to force subclassing, making the class abstract is better; if it's to have a class with utility methods, making it static is one way (then you can only have static methods).
I need to know how to prevent a class from being Instantiated in .net?
Your question is not clear.
Do you mean instantiated at runtime? Make the class abstract or static.
Do you mean that the constructor is not accessible in code? Make the constructor private. But note that someone could still use reflection to grab a handle on a constructor and instantiate an instance at runtime.
So, which do you mean?
If the question is:
How can you make your class not be instanced without having your class
be static or abstract?
Then the answer to this is to implement the singleton pattern, which in .NET 4+ this is done easily with:
public sealed class myClass
{
private static readonly Lazy<myClass> lazyInstance =
new Lazy<myClass>(() => new myClass());
public static Instance
{
get
{
return lazyInstance.Value;
}
}
private myClass()
{
// constructor logic here
}
}
The singleton pattern allows you to pass your class around as a reference to methods, while still ensuring that you have only a single instance of your class. It also makes testing much easier as you can have a ImyClass instance which myClass implements, this is very helpful when making mock objects.
Without .NET4 you can still implement the singleton pattern, for example:
private static readonly myClass instance = new myClass();
public static Instance
{
get
{
return instance;
}
}
// rest of code remains the same
Which doesn't have deferred loading until it's called, there's lots of other ways as well (I think about 6 different ways), but the above two are the most common ones.
In summary the question is likely asking if you know the singleton pattern and if you recognise it's importance over static classes for unit tests and mock objects.
As others have already pointed out, static fields, even those marked readonly can be set with reflection, in addition the private constructor can be called using reflection. If you need to prevent these, either you need to make the calling code run in a less trusted app-domain space, or you will need to implement your class as static.
Generally though, people don't bother with such levels of reflection to get around your constraints unless they 'really need to' for example, writing obscure / extreme fringe case unit tests.
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.
I have two objects that I will be mainly use inside of single class. I will initialize them at the beginning and use them throughout the life of the program. Now, my question is that if I should just create them as global variables and access them anywhere in the code (in side of single class) or I should create them as local variables and pass them as parameters to other functions. I just want to see what would be the best programming practice.
I am using C#.
Thanks.
In general you should avoid global variables. If it will be practical, I recommend keeping them as locals and passing them as parameters to your functions.
As Josh pointed out, if these variables are only used inside a single instance of the class, then you should just make them private (or protected) members of that class and be done with it. Of course, then they could only be passed in as parameters to other methods with the same access level (IE, private).
Alternatively, you may consider using the Singleton Design Pattern, which is slightly cleaner (and preferable) to using globals.
If the scope of the objects is the lifetime of the class they are instantiated in, then they should be private member variables.
If they do not maintain state themselves, then you should make them static classes.
You should still pass them around as variables, or at least create property accessors to get at the backing field. This way you can change implementation details without blowing up your code.
SOLID design principles are a good place to start when thinking about these things.
I have two objects that I will be
mainly use inside of single class. I
will initialize them at the beginning
and use them throughout the life of
the program.
This sounds like a perfect time to use a private static readonly variable. These can be initialized in their declaration, or you can make a static constructor to initialize them.
The fact that you are only referencing these objects within a single class is key point. There are other better ways to do things if these objects are ever needed outside of the single class.
If the objects will be the same for every instance of the class then
static const double PI = 3.14158;
You should generally use accessor methods (e.g. getters and setters) and keep your internal variables private. This way the rest of your code, outside of your class, is not dependent on your actual variables.
See this tutorial.
If your class is dependent on these 2 objects then they should probably be members on the class itself. Something like this (where A is the class you are talking about and B is one of the objects you initialize:
public class A
{
private B _b;
public A(B b)
{
_b = b;
}
public void DoSomething()
{
//do something with _b;
}
private void DoSomethingElse()
{
//do something else with _b;
}
}
In this example A is dependent on B (so you pass your instance of B into A's constructor or through some Dependency Injection framework). It wouldn't make a lot of sense for every method on class A to need a parameter of type B to be passed to it.
I think in this case you should ask what makes more sense. Is there some kind of relationship between the 2 objects and the new class. Also, how often are they used in the class.
Generally, If only a couple of methods use the objects, pass them around otherwise, instantiate them as class level variables (possibly using private static readonly as Jefferey suggests) and use them in the class. Making the code more readable should be your goal here.
The title is pretty much my entire question.
I'm doing a code review for an off-shore developer who has several static methods inside a non-static class. Before I challenge the developer and mark this as "needs changing", I just want to make sure.
I understand the purpose of a static class: It can not be instantiated and can be used directly. But I can't see any reason to have a static method in a non-static class. Is there any valid use-case for this?
The methods in question are all private and are called from non-static methods.
Here's an example:
public ViewResult ClaimDetails(ClaimDetails claim)
{
if (claim.ClaimNumber != 0)
{
claim = Get_ClaimDetails(claim);
}
return View("ClaimDetails", claim);
}
private static ClaimDetails Get_ClaimDetails(ClaimDetails claim)
{
ClaimsRepository claimsRepository = new ClaimsRepository();
_claimDetails = new ClaimDetails();
_claimDetails = claimsRepository.GetClaimDetails(claim.ClaimNumber);
return _claimDetails;
}
There are a few things that would raise an eyebrow with me, but the method signature is fine.
static is a keyword that makes sure the method does not use instance members. That's great. It clearly signals this to other developers. I would have argued for the opposite side: a method should be marked static, except when needed otherwise.
Many tools and even Visual Studio itself would flag it if you did not mark it static: CA1822: Mark members as static.
Quoting Microsoft:
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 run time 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.
So to summarize it: it's perfectly fine as it is.
Reading all the additional comments: it seems the real problem is that an injected repository already exists and the whole method should scrapped and replaced by the line claim = this.injectedClaimsRepository.GetClaimDetails(claim.ClaimNumber);. But that's a whole other problem. The keyword static is perfectly fine if used correctly, the posted code did not show it wasn't.
For example, it's an often-used approach to have multiple static factory methods in cases where it is undesirable to expose the internal implementation.
Car hatchback = Car.CreateHatchback();
Car sedan = Car.CreateSedan();
In this example, both instances have a hidden internal implementation of factory methods, possibly instantiating specialized internal subclasses or calling internal constructors.