I use resharper and resharper adviced me to declare one method as static and the another not. But i can't understand why the other method can't be static ?
method recommended to be static
private static string Prehod(string retazec)
{
var pole = retazec.ToCharArray();
var output = "";
char? temp = null;
for (var i = 0; i < pole.Length; i++)
{
if (temp == null)
{
temp = pole[i];
continue;
}
output += pole[i].ToString() + temp.ToString();
temp = null;
}
return output;
}
and method not recommended to be static
public string HashToString(string hash,int dlzka)
{
var hashChar = hash.Substring(0, dlzka*2);
var retazec = "";
for (var i = 0; i < dlzka*2; i++)
{
if(i%2 != 0)
{
retazec += hashChar.Substring(i, 1);
}
}
return retazec;
}
Resharper doesn't give advices on public members of your classes, since they can be used by other classes.
But it's still a sign (not to say 'smell') for you if public instance methods don't need instance at all.
I can't see any reason why the second method can't be static, as to why Resharper suggests one and not the other... you'd have to ask the Resharper developers. Remember, it's a tool, not a rule book.
I don't see why your second method couldn't be static. As far as I can tell, it doesn't access any instance fields.
It wouldn't be a problem mnaking it static. So much to your question why it couldn't be static. As for ReSharper, I don't know why it doesn't recommend it as static whereas it does this for the other method.
Your first method is private, and probably used statically inside the class. Eg: var ehy = Prehod("testing");.
The second method is public. Probably you use it already somewhere like:
var okBaby = new MyClass();
Console.WriteLine(okBaby.HashToString("something", 10));
And resharper probably thinks there is a reason for it to be so, and doesn't suggest the change.
Just a blind shot, though.
Both methods can be static: they don't use any instance members of your class. And both methods can be instance methods. But a method being static or not should be implied by the possible uses of it, not by ReSharper. Do you expect your method to be called as part of an instance:
YourClass instance = new YourClass();
string x = instance.Prehod(...);
or do you expect your method to be called as part of the class:
string x = YourClass.Prehod(...);
It can be much later in the development process before you realize which is best. If you want to give users of your class the "feel" that it acts on the instance (new ClassName()), you must choose instance method. If you really need the method to be used without an instance (ClassName.YourMethod()) you must choose static.
UPDATE: it is uncommon to make a private method static, unless you need other static methods to call the private static methods. If only other instance methods use your private method, then there's no reason to make it a static method whatsoever.
Related
I wanted to make a .ToList() extension method for the Recipients object for Outlook, but I wasn't sure if it's good practice. Would it create an extra reference to the object that would need to be cleaned up or would it be fine as long I clean up the original Recipients object? The extension would be used something like this.
private void Foo()
{
Recipeints recipients = mailItem.Recipients //Original recipients
if(recipients.ToList().Intersect(listOfRecipients).Any())
{ }
OutlookEx.ReleaseComObject(ref recipients);
}
public static class Extensions
{
public static List<string> ToList(this Outlook.Recipients recipients)
{
List<string> list= new List<string>();
if(recipients == null)
return null;
for (int i = 1; i <= recipients.Count; i++)
{
Outlook.Recipient r = recipients[i];
list.Add(r.Name);
OutlookEx.ReleaseComObject(ref r);
}
return list
}
}
Extensions methods are just static methods
Creating extensions methods do not cause an extra reference to be created, extension methods are syntactic sugar for static methods, they are still static methods but just allow you to call them in a more user-friendly way.
var ls = Extensions.ToList(recipients)
//is equivalent to
var ls = recipients.ToList()
You still need to clean up your COM objects correctly
That being said you still need to clean up and manage unmanaged resources correctly being inside of a static method, shouldn't be handled any differently than if you were implementing the method anywhere else
An extension method is, cost wise, no different than an instance method. An instance method has a hidden parameter pointing to self, the instance method has the same concept, only it's not hidden to the developer. The call stacks end up looking the same, and the memory pressure is the same.
In other words, if you consider it reasonable to use a function, there's no reason (other than style and reusability) to make it an extension method.
Would it create an extra reference to the object that would need to be cleaned up or would it be fine as long I clean up the original Recipients object?
No - extension methods are just static methods that can be called a different way. So long as you're not storing the recipients parameter somewhere, it will go out of scope as soon as the method completes and will not need to be "cleaned up". But that would be no different if it were a static non-extension method or an instance method.
I want to create a wrapper class for another type. This works fine until the point where it's necessary that (reference)-equal objects need to have (reference)-equal wrappers.
An example:
public interface ITest<T>
{
T GetInstance(bool createNew);
}
public class Test : ITest<Test>
{
private static Test instance;
public Test GetInstance(bool createNew)
{
if (instance == null || createNew)
{
instance = new Test();
}
return instance;
}
}
public class TestWrapper : ITest<TestWrapper>
{
private readonly Test wrapped;
public TestWrapper(Test wrapped)
{
this.wrapped = wrapped;
}
public TestWrapper GetInstance(bool createNew)
{
return new TestWrapper(wrapped.GetInstance(createNew));
}
}
Test.GetInstance returns always the same instance, as long as the parameter createNew is false.
By contrast TestWrapper.GetInstance returns always a new instance.
Since I want to be able to replace Test with TestWrapper, I search for a solution so that at the end, the wrapper returns a new instance only, if Test returns a new instance. However, the TestWrapper should have no knowledge about the internals of Test.
The test code is
private static void RunTest<T>(ITest<T> cls)
{
var i1 = (ITest<T>)cls.GetInstance(false);
var i2 = (ITest<T>)cls.GetInstance(false);
var i3 = (ITest<T>)cls.GetInstance(true);
var dic = new Dictionary<ITest<T>, bool>();
if (!dic.ContainsKey(i1)) dic.Add(i1, false); else dic[i1] = true;
if (!dic.ContainsKey(i2)) dic.Add(i2, false); else dic[i2] = true;
if (!dic.ContainsKey(i3)) dic.Add(i3, false); else dic[i3] = true;
Console.WriteLine(string.Join(", ", dic.Select(a => a.Value.ToString())));
}
The desired result is
True, False
and that's what you get if one passes new Test() to that method.
If you pass new TestWrapper(new Test()), you'll get
False, False, False
There is a solution based on a simple cache (Dictionary<Test, TestWrapper>) - but with that, I would hold many of the instances in memory without using them any further (and the GC could not collect those instances since there's a reference holding them).
I played around with WeakReferences a bit, but I can't spot a key that I can use to store the WeakReference - thus I have to iterate through the cache list and search for the correct instance which is slow. Besides, I've to implement this solution for every member (with it's very own cache) which seems not to be a great solution...
I hope I have adequately explained my problem ;) So, my questions are:
is there a way to cheat object.ReferenceEquals (that question is unrewarding)
what can I use (as a key for the cache) as an identifier for an object instance (so I can use WeakReference)
is there a better way to achieve a real adapter (where I can replace the adaptee with an adapter without headache)
I've no access to the Test class, and only limited access to the code that uses it (I'm able to pass an arbitrary instance as long it's implements the interface)
No, you can't cheat object.ReferenceEquals(). However, object.ReferenceEquals() is intentionally used very rarely, and usually in cases where things really do need to be reference-equal.
The runtime need it in order to get things right. E.g. if the instance is used as a key in an Dictionary<>
Actually, the runtime typically uses the .GetHashCode() and .Equals() behavior of the individual objects, but it just so happens that if you don't override that behavior in your classes, the base System.Object implementation of those methods relies on the object reference by default.
So if you have the ability to change the code for both the Test class and the TestWrapper class, you can override these equality methods in those classes to ensure that they recognize equivalent objects as equal.
An alternative (and usually better) approach would be to create an IEqualityComparer<> implementation to use in your specific use case. You mentioned keys in a Dictionary<>: you can provide an IEqualityComparer<> instance to the dictionary when it's created to have it test for equality in exactly the way you want.
var dict = new Dictionary<object, object(new TestsAndWrappersAreEqualComparer());
var test = Test.GetInstance(true);
var testWrapper = TestWrapper.GetInstance(true);
dict[test] = test;
Console.WriteLine(dict.ContainsKey(test)); // true
So I have a number of different potential object that can output data (strings). What I want to be able to do, is to Run a generic Output.WriteLine function, with the potential arguments that define where you want it to be outputted to. What I've got for code -
//Defined in static class Const
public enum Out : int { Debug = 0x01, Main = 0x02, Code = 0x04 };
static class Output
{
private static List<object> RetrieveOutputMechanisms(Const.Out output)
{
List<object> result = new List<object>();
#if DEBUG
if (bitmask(output, Const.Out.Debug))
result.Add(1);//Console); //I want to add Console here, but its static
#endif
if (bitmask(output, Const.Out.Main))
if (Program.mainForm != null)
result.Add(Program.mainForm.Box);
if (bitmask(output, Const.Out.Code))
if (Program.code!= null)
result.Add(Program.code.Box);
return result;
}
public static void WriteLine(Color color, string str, Const.Out output = Const.Out.Debug & Const.Out.Main)
{
Console.WriteLine(
List<object> writers = RetrieveOutputMechanisms(output);
foreach (object writer in writers)
writer.WriteLine(str, color);
}
}
The point of this, is that the output destinations are not always existent, as they are on forms that may or may not exist when these calls are called. So the idea is to determine which ones you're trying to print to, determine if it exists, add it to the list of things to be printed to, then loop through and print to all of them if they implement the "WriteLine" method.
The two problems that I've come across, are
That Console is a static class, and can't properly (as far as my knowledge goes) be added to the object list.
I don't know how I can assert that the objects in the list define WriteLine, and cast them to something that would apply to more than one base Type. Assuming I can get Console to work properly in this scheme, that would be the obvious problem, its not of the same base type as the actual Boxes, but also, if I had something that wasnt a Box, then it would be lovely to do something like
foreach (object writer in writers)
.WriteLine(str, color)
so that I wouldn't have to individually cast them.
The bigger reason that I don't simply WriteLine from the RetrieveOutputMechanisms function, is that I want this to cover more than just WriteLine, which means that I would need to copy the bitmask code to each function.
EDIT: I realise that adding public properties to Program is a bad idea, if you know how I can avoid it (the necessity coming from needing to be able to access any WriteLine-able form objects that come and go, from anywhere), by all means please elaborate.
One way would be to use an Action (a delegate) and store those in your List. This will work for Console and any other class as you can easily write a lambda (or a 2.0 delegate) to map your output variables to the right parameters in the called method. There will be no need for casting. It could work something like this:
(This assumes you are using C# 3.5 or later but you can do all this in anything from 2.0 and on using delegates)
static class Output
{
private static List<Action<string, Color>> RetrieveOutputMechanisms(Const.Out output)
{
List<Action<string, Color>> result = new List<string, Color>();
#if DEBUG
if (bitmask(output, Const.Out.Debug))
result.Add((s, c) => Console.WriteLine(s, c)); //I want to add Console here, but its static
#endif
if (bitmask(output, Const.Out.Main))
if (Program.mainForm != null)
result.Add((s, c) => Program.mainForm.Box.WriteLine(s, c));
if (bitmask(output, Const.Out.Code))
if (Program.code!= null)
result.Add((s, c) => Program.code.Box.WriteLine(s, c));
return result;
}
public static void WriteLine(Color color, string str, Const.Out output = Const.Out.Debug & Const.Out.Main)
{
var writers = RetrieveOutputMechanisms(output);
foreach (var writer in writers)
writer(str, color);
}
}
(edit to add)
You could change this more significantly to allow classes to "register" to be able to do the writing for a specific "output mechanism" in the Output class itself. You could make Output a singleton (there are arguments against doing that but it would be better than sticking public static variables in your main program for this purpose). Here is an example with more significant changes to your original class:
public sealed class Output
{
private Dictionary<Out, Action<string, Color>> registeredWriters = new Dictionary<Out, Action<string, Color>>();
public static readonly Output Instance = new Output();
private void Output() { } // Empty private constructor so another instance cannot be created.
public void Unregister(Out outType)
{
if (registeredWriters.ContainsKey(outType))
registeredWriters.Remove(outType);
}
// Assumes caller will not combine the flags for outType here
public void Register(Out outType, Action<string, Color> writer)
{
if (writer == null)
throw new ArgumentNullException("writer");
if (registeredWriters.ContainsKey(outType))
{
// You could throw an exception, such as InvalidOperationException if you don't want to
// allow a different writer assigned once one has already been.
registeredWriters[outType] = writer;
}
else
{
registeredWriters.Add(outType, writer);
}
}
public void WriteLine(Color color, string str, Const.Out output = Const.Out.Debug & Const.Out.Main)
{
bool includeDebug = false;
#if DEBUG
includeDebug = true;
#endif
foreach (var outType in registeredWriters.Keys)
{
if (outType == Const.Out.Debug && !includeDebug)
continue;
if (bitmask(output, outType))
registeredWriters[outType](str, color);
}
}
}
Then elsewhere in your program, such as in the form class, to register a writer, do:
Output.Instance.Register(Const.Out.Main, (s, c) => this.Box.WriteLine(s, c));
When your form is unloaded you can then do:
Output.Instance.Unregister(Const.Out.Main);
Then another way would be to not use a singleton. You could then have more than one Output instance for different purposes and then inject these into your other classes. For instance, change the constructor for your main form to accept an Output parameter and store this is an object variable for later use. The main form could then pass this on to a child form that also needs it.
If your objects that have data that need to be written behave like this:
A always writes to console and log
B always writes to log
C always writes to console
For all data, then your best bet would be to declare an interface and have each of them implement the interface method for output. Then, in your calling code, declare them not as their actual types but instead of type IOutput or whatever interface u call that has the method. Then have two helper methods, one for actually outputting to console and one for actually outputting to a log file. A would call both helpers, B and C their respective ones.
If, on the other hand, your objects will write to various logs at differing times:
A, B and C sometimes write to console and sometimes to log, depending on some property
Then I would recommend you create an event handler for when a class wants something to be written. Then, have the logic that discerns what writes to console and what writes to log in a listener class and attach the appropriate ones to that output event. That way, you can keep the logic about what is being written to where in classes that encapsulate just that functionality, while leaving the A, B and C classes free of dependencies that may come to bite you down the road. Consider having a monolithic method as you describe which uses a bitmask. As soon as the behavior of A, B or C's logging changes, or if you need to add a new output, you suddenly need to worry about one class or method affecting all of them at once. This makes it less maintainable, and also trickier to test for bugs.
MethodInfo methodname = typeof(object).GetMethod("MethodA");
Then just use a if statement to check if methodname is null or not.
I'm trying to use this great project but since i need to scan many images the process takes a lot of time so i was thinking about multi-threading it.
However, since the class that makes the actual processing of the images uses Static methods and is manipulating Objects by ref i'm not really sure how to do it right. the method that I call from my main Thread is:
public static void ScanPage(ref System.Collections.ArrayList CodesRead, Bitmap bmp, int numscans, ScanDirection direction, BarcodeType types)
{
//added only the signature, actual class has over 1000 rows
//inside this function there are calls to other
//static functions that makes some image processing
}
My question is if it's safe to use use this function like this:
List<string> filePaths = new List<string>();
Parallel.For(0, filePaths.Count, a =>
{
ArrayList al = new ArrayList();
BarcodeImaging.ScanPage(ref al, ...);
});
I've spent hours debugging it and most of the time the results i got were correct but i did encounter several errors which i now can't seem to reproduce.
EDIT
I pasted the code of the class to here: http://pastebin.com/UeE6qBHx
I'm pretty sure it is thread safe.
There are two fields, which are configuration fields and are not modified inside the class.
So basically this class has no state and all calculation has no side effects
(Unless I don't see something very obscure).
Ref modifier is not needed here, because the reference is not modified.
There's no way of telling unless you know if it stores values in local variables or in a field (in the static class, not the method).
All local variables will be fine and instanced per call, but the fields will not.
A very bad example:
public static class TestClass
{
public static double Data;
public static string StringData = "";
// Can, and will quite often, return wrong values.
// for example returning the result of f(8) instead of f(5)
// if Data is changed before StringData is calculated.
public static string ChangeStaticVariables(int x)
{
Data = Math.Sqrt(x) + Math.Sqrt(x);
StringData = Data.ToString("0.000");
return StringData;
}
// Won't return the wrong values, as the variables
// can't be changed by other threads.
public static string NonStaticVariables(int x)
{
var tData = Math.Sqrt(x) + Math.Sqrt(x);
return Data.ToString("0.000");
}
}
I have this code:
public class EntityMapper<T> where T : IMappingStrategy, new()
{
private static T currentStrategy;
public static T CurrentStrategy
{
get
{
if (currentStrategy == null)
currentStrategy = new T();
return currentStrategy;
}
}
}
Then:
public static void Main()
{
EntityMapper<ServerMappingStrategy>.CurrentStrategy.ToString();
EntityMapper<ClientMappingStrategy>.CurrentStrategy.ToString();
EntityMapper<ServerMappingStrategy>.CurrentStrategy.ToString();
}
Well, the question is:
Why when i'm debugging i can see that the constructor of ServerBussinessMappingStrategy is called only once time?
This work well, but i undertand why always EntityMapper return the correct instance that i need, only instantiating once time the ServerMappingStrategy class.
Regards!
PD: Sorry my english jeje ;)
The static field is persisted for the duration of your AppDomain, and it is cached when first created:
public static T CurrentStrategy
{
get
{
if (currentStrategy == null) // <====== first use detected
currentStrategy = new T(); // <==== so create new and cache it
return currentStrategy; // <=========== return cached value
}
}
Actually, there is an edge case when it could run twice (or more), but it is unlikely.
This is a pretty common pattern for deferred initialization, and is used pretty much identically in a number of places in the BCL. Note that if it had to happen at most once, it would need either synchronization (lock etc) or something like a nested class with a static initializer.
Normally, it will only get called once. That is, unless you have a race condition.
Let's say two threads execute this statement the same time:
EntityMapper<ServerMappingStrategy>.CurrentStrategy.ToString();
Let's say thread A will run up until currentStrategy == null but gets paused before new T() when Windows suddenly gives control to thread B which then makes the comparison again, currentStrategy is still null, invokes the constructor and assigns the new instance to currentStrategy. Then, at some point, Windows gives the control back to thread A that calls the constructor again. This is important because normally static members are (sort of) expected to be thread safe. So if I were you, I would wrap that bit into a lock clause.
P.S. this snippet won't compile as T might be a struct that cannot be a null. Instead of comparing to null, compare to default(T) or specify that T has to be a class.