Replacing all usages of a method (Introduce Indirection) - c#

I am generally not very fond of refactoring tools. No need to get into details. Still, I occasionally try out new versions. Here is what I was trying to do while evaluating resharper 4.5 :
I needed to replace all usages of a method with a wrapper method (to be created) but I could not. I usually suck at noticing an obvious feature, is this the case? If resharper does not have this feature, do you know such tools?
Edit 2: Sample has been improved to include instance method calls.
Edit:
Here is a simple case to play.
static void Main(string[] args)
{
while(true)
{
if (Console.ReadKey().Key == ConsoleKey.Escape)
{
Thread.Sleep(10);
if (Quiting()) break;
}
Console.Beep(250, 50);
}
}
static bool Quiting()
{
if (Console.In.Peek() > 0)
{
Console.Beep(250, 150);
return false;
}
return true;
}
What I need is something like: (Edit2: added an instance sample)
private static StringBuilder _builder = new StringBuilder();
static void Main(string[] args)
{
while(true)
{
var key = Console.ReadKey();
if (key.Key == ConsoleKey.Escape)
{
Thread.Sleep(10);
if (Quiting()) break;
}
_builder.Append(" (").Append(key.KeyChar).Append(") ");
Beep(250, 50);
}
}
static bool Quiting()
{
if (Console.In.Peek() > 0)
{
Beep(250, 150);
_builder.Append('#');
return false;
}
return true;
}
static void Beep(int frequency, int duration)
{
// finally cursor ends up here
Console.Beep(250, 50);
}
Console.Beep calls are refactored. Next lets refactor StringBuilder.Append(char) :
class Program
{
private static StringBuilder _builder = new StringBuilder();
static void Main(string[] args)
{
while(true)
{
var key = Console.ReadKey();
if (key.Key == ConsoleKey.Escape)
{
Thread.Sleep(10);
if (Quiting()) break;
}
_builder.Append(" (").AppendUpper(key.KeyChar).Append(") ");
Beep(250, 50);
}
}
static bool Quiting()
{
if (Console.In.Peek() > 0)
{
Beep(250, 150);
_builder.AppendUpper('n');
return false;
}
return true;
}
static void Beep(int frequency, int duration)
{
// finally cursor ends up here
Console.Beep(250, 50);
}
}
static class StringBuilderExtensions
{
public static StringBuilder AppendUpper(this StringBuilder builder, char c)
{
return builder.Append(char.ToUpper(c));
}
}
Selecting from usages and maybe omitting common parameters (such as 250 above) or common instance parameters for non-extension statics shall make this feature more valuable. Hopefully, this clears up the question.

ReSharper doesn't have this as a single refactoring. I might do it as follows:
Select the contents of the method to be wrapped, and use Extract Method to create a new private method from the contents.
The original method is now a trivial wrapper around "itself". Rename it if you like, or manipulate it as you like (make it static, move to a different class, surround with try/catch, whatever).
EDIT:
Based on your edit, it seems you have an additional problem. Not only is Console.Beep not in the same class, it's not even in your class.
But if you don't mind a little search and replace, then you can put it into your own class, then proceed with the refactoring:
namespace Temporary {
public class Console {
public static void Beep(int x, int y) {System.Console.Beep(x,y);}
}
}
Then do a "Replace in Files" to replace Console.Beep with Temporary.Console.Beep, and proceed as above.

It's not included in any .NET refactoring IIRC, the tool which has such a refactoring is Eclipse, but not for .NET/C#

Assuming the wrapper method will be in the same class you can rename the current method to the name of the new wrapper method (ctrl+R+R in Resharper). This will rename all calls to this method in the solution as well. Then rename the original method back by hand (don't use Resharper or all the calls will get renamed back too) and add the wrapper method.
Based on your edit I think you will be out of luck to get the functionality that you want from any Visual Studio add-in that I've seen (beyond the simple find and replace which will get you some of the way there I guess).
Depending on how much time and effort you are willing to devote to this I'd imagine it's possible to use the DXCore framework and write a plugin that will do this kind of refactoring.

Resharper has a Search and Replace with Pattern feature. It can search and replace on patterns and expressions.
This would refactor all calls to Console.Beep() to your own method. It only replaces the usage if 250 is the first parameter:
However this would replace the usage of Console.Beep() within your own Beep method. You would have to manually replace that one usage.

Related

How can I use one function, which belongs to two objects, for only one objects?

I am writing a c# monogame.
On the map there are two goldmines. The player can collect the gold with the following method:
public static void CollectGold(ObjectFactory.ObjectType type)
{
if (Hud.mCurrentTime >= Hud.mCountDuration)
{
Counter++;
Hud.mCurrentTime -= Hud.mCountDuration
if (sMaxGold < 10)
{
sMaxGold += 2;
}
if (sMaxGold >= 10)
{
sMaxGold -= 2; // or sMaxGold = 10 in earlier version-> same output
}
}
else if (sMaxGold > 0)
{
Hud.mGold += 2;
sMaxGold -= 2;
}
}
But for sure, when the player collects gold from goldmine, it is like, he is collecting gold from the other mine as well.
How can I seperate this, that CollectGold only works for the one selected mine.
I can't create CollectGold2 with the same code for the second mine, because one time I want to build a lot of mines in my code. I think there is a better way, than copy and paste the method.
My first idea was, that i can check the mine position, so that the method knows the one mine.
But I don't know how to do it?
Any ideas?
You should use a custom class for a mine and make a non-static method there instead of a static one. Then you should just find the mine needed and collect it's gold. Example:
private class Player
{
public int GoldBalance = 0;
}
private class Mine
{
public int GoldAvailable = 10;
public void Collect(Player player)
{
if (GoldAvailable <= 0)
return;
player.GoldBalance += GoldAvailable;
GoldAvailable = 0;
}
}
This question isn't really answerable in this form; we need more information. For example, how are you representing your mines in code?
However, here are a couple of possible approaches:
Move your method to the Mine class (if it exists), so that you call the method something like this:
var mine = new Mine();
mine.CollectGold();
Pass a Mine object, or the id of a mine, to the method, so that the signature would look like this:
public static void CollectGold(Mine mine)
or
public static void CollectGold(int mineId)
I have removed the type parameter which was unused.
Method 1 is probably preferable but it depends what you're trying to achieve and how complex your application will be.

Arrays in Methods and Returning to Main

I would like to know how to go from a method back to main. For example, I want to check if number passes a certain criteria; I would perform a test in a different method and if it returns true, I want to continue using that number back in main. How can go from one method to main again in a continuous loop? I tried calling the main method but the program displays a message for error.
The way my project is set out is that a menu appears for the user to enter a postal code. The menu has many options to add, quit, or view their codes. Once they have added their postal code and it is valid, how can I loop it back to main with the menu appearing again, performing the same functions?
Small section from main:
if (decision.Equals("A"))
{
Console.Write("\n");
Console.WriteLine("Please enter your postal code: ");
for (i = 0; i < 1; i++)
{
postalcodez = Console.ReadLine().ToUpper();
if (isValid(postalcodez, i, number, j, num))
{
postalcode[i] = postalcodez;
Console.WriteLine("It worked!");
Console.ReadLine();
}
}
}
Now it goes through the method to check for conditions. If it returns true, how can I make it go back to main?
public static bool isValid(string postalcodez, int i, int number, int j, int num)
{
if (postalcodez.Length > 7 || postalcodez.Length < 7)
{
return false;
}
if (postalcodez[0].ToString().Equals("W") || postalcodez[0].ToString().Equals("Z"))
{
return false;
}
if (postalcodez.Length.Equals(7))
{
if (postalcodez[3].ToString().Equals(" "))
{
return true;
}
else
{
return false;
}
Another question is that how can I make an array so that I can set a condition for a specific character number. Instead of doing this ( where I hard code specific digits) I want it that the 1, 4 and 6th character must be a certain value :
if (postalcodez[1].ToString().Equals(0) || postalcodez[1].ToString().Equals(1) || postalcodez[1].ToString().Equals(2) || postalcodez[1].ToString().Equals(3) || postalcodez[1].ToString().Equals(4))
{
return true;
}
Since this is for school, I can use any special functions to resolve the issue. It has to be very basic.
It seems like you have a bit of a misunderstanding of what Main() actually is. Main() is, in effect, your entire application. Main is the root that everything will flow back to when the current call stack finishes resolving, and if there are no additional statements after that point, Main will complete, and the application will close. When you call methods from Main, when they return a value (if not void), you are then back inside of Main.
Based on what you have stated is your need, here is a very basic example of what will happen - the flow of the code should be reasonably clear:
private static void Main(string[] args)
{
int number = 5;
bool isValid = VerifyNumber(number);
if (!isValid)
Console.WriteLine("Not valid.");
else
Console.WriteLine("Valid.");
Console.ReadKey();
}
private static bool VerifyNumber(int number)
{
return number > 2;
}
Things to take note of:
Since the method being called from Main has an argument, that argument is provided from inside of Main. This means that when the method finishes, Main still has access to that value.
The output of the method is stored so that work can be done inside of Main based on it.

C# MultiThreading: pool of calculators

I want to have a static (global) pool of calculators which are going to be accessed by a lot of different threads.
After some researching I found out that the elements of Arrays are threadsafe.
I thought that it would be good idea to store the diffrent calculators (amount unknown until runtime) in a static array (calculator[] calculators).
How do I ensure that only one calculator is being used by one calculator?
I read the whole msdn documentation so don't post "only" links please.
I have also thought about a bool array "locked" but I can't find a way to implement this threadsafe.
My code so far:
internal static class Calculators
{
private static Semaphore pool;
private static bool[] locked;
private static calcs[] neuralNetworks;
private static Thread[] threads;
internal static Calculators(){
int number = Globals.Number;
pool = new Semaphore(number, number);
locked = new bool[number];
calcs = new calcs[number];
threads = new Thread[number];
for (int index = 0; index < number; index++)
{
// all neuralNetworks are unlocked by default
locked[index] = false;
// generate one network per "countThreads"
calcs[index] = Globals.CalcObj;
// generate one thread for each neural network
threads[index] = new Thread(new ThreadStart());
}
}
private int WhichCalculators()
{
int index;
for (index = 0; index < countThreads; index++)
{
if (locked[index] == false)
{
locked[index] = true;
return index;
}
}
throw new Exception("Calculators was called, but there weren't any networks unused");
}
}
Code Update:
So should it work, if I call "WhichCalculator()" in this method?
private static void doStuff()
{
pool.WaitOne();
Monitor.Enter(thisLock);
try
{
int whichCalculator = WhichCalculator();
locked[whichCalculator] = true;
lock (calculators[whichCalculator])
{
Monitor.Exit(thisLock);
// do stuff
locked[whichCalculator] = false;
}
}
catch
{
Monitor.Exit(thisLock);
}
//Calculate();
pool.Release();
}
Question 2:
Am I right to assume, that the static constructor is going to be executed as soon as (but before) the first time this class or any member of it is going to be accessed?
Yes you have to use lock. But the array and every instance of calculator again.
If you can fill the array before you start the multithreaded section of your code you need not lock the array as well (only reading doesn't make problems due to the static content) but with resizing the array you need to lock every access to it (writing AND reading).
So your code could look like this:
Calculator calc = null;
lock(calculators)
{
calc = calculators[0];
}
lock(calc)
{
// ... do stuff
}
This way the array isn't longer locked then needed and you can lock the calculator itself.
You can lock your array. That would ensure that every array-operation is executed thread-safe.
To ensure, that each object is only used once at a time you can add a flag to it, like calculator.InUse. If you can't add a flag to the class, you can use an extension method.

How call the main method or restart the app console?

When an exception occurs I want to restart all the processing or start the Main method, after this other method:
public void DisplayMessage(string message) {
Console.WriteLine(message, "Rebuild Log Files");
Console.WriteLine(" Press Enter to finish, or R to restar the program...");
string restart = Console.ReadLine();
if(restart.ToUpper() == "R") {
//Call the Main method or restart the app
}
Console.ReadKey();
}
Note: the main method contains some user written data.
How can I do this?
Ok you have a main
void main(...)
{
some code
}
All you need to do is...
void main()
{
runStartUpCode();
}
void runStartUpCode()
{
some code
}
Then when you need to restart the code, call runStartUpCode() again.
if(restart.ToUpper() == "R") {
Close();
System.Diagnostics.Process.Start(Application.ExecutablePath);
}
static void Main(string[] args) {
try {
// code here
} catch /* or finally */ {
DisplayMessage(/* pass in any state from Main() here */);
}
}
static void DisplayMessage(/* passed in state from Main() */) {
// original DisplayMessage() code
// if R was pressed
Main(/* put any args to pass to Main() in here */);
}
I actually just got done with this problem earlier by the time you read this post. I kind of duplicated the ORIGINAL main method, changed a few options on the original, and left the copy to call the new main method. Here is what I mean.
static void Main(string[] args)
{
Program CallingTheRealMain = new Program();
CallingTheRealMain.Main2();
}
public void Main2()
{
//Any code here
}
I originally needed to do this because I needed to loop back to the main method but couldn't because it was static. This code worked fine for me, hope it does for you too if you choose to implement it. Hope I helped. Happy coding!
DialogResult result = MessageBox.Show("Do You Really Want To Logout/Exit?", "Confirmation!", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
this.Close();
System.Diagnostics.Process.Start(Application.ExecutablePath);
}
I think your design approach should change if what your app to autorestart.... here's a Pseudocode
main (){
errorObj = null;
internalFunct(errorObj);
if(errorObj != null) return;
secondINternalFunction();
}
Running the app...
while(!errorObj){
main();
}
Why i prefer this approach, because Main, or function recall is avoided... If your working with small memory, there is not point recalling main on the stack of limited space... you have no choice but to be iterative...
New to C#, I apologize for mistakes.
Use this:
static void Restart() {
String[] n = new String[10];
n[0] = "hi";
Main(n);
}
Main takes a string array for reasons I am unaware of. Seems useless to me, because I tried removing it and nothing seemed to change. So, maybe this works too:
Try removing the string[] args part of Main() so you can just type Main(); without
issues.

Stop a loop inside a method in C#

Is there any way to stop a running loop inside another method or insert a break statement dynamically in C#?
Thanks
Edit : I want to be able to dynamically intercept the method and insert a break to stop the loop when an event gets triggered in another function.I have several instances of the class and I want to stop the loop in each instance whenever required and manage all the instances. Consider multiple instances to be in a generic list
Example :
List<myclass> objlist=new List<myclass>();
foreach(myclass obj in objlist)
{
obj.loopingfunction().BreakLoop //or something like this (assuming that the loopingfunction is already called)
}
I need this because I want to break the loop once the user stores some huge amount of data.When the user imports the data,I get a event fired. But I cannot keep checking the database from multiple instances since it screws up sqlserver.
This is in an ASP.Net application.
If the whole thing is running in a single thread, it wouldn't make any sense. If the loop is running, then nothing else is running at the same time. If you're running a loop on another thread and the controlling method on another thread, you can either abort the loop thread completely or check a flag inside the loop to decide whether or not you should break and set the flag appropriately in the controlling method.
Update: make that function return a boolean value indicating whether you should break and use it in an "if" statement:
if (myFunctionShouldBreakLoop()) break;
Another option would be to raise a CancelEventArgs during every iteration of the loop. Probably not the most efficient, but another option nonetheless:
private void SomeMethod()
{
for (int i = 0; i <= 100000; i++)
{
Console.WriteLine(i);
if (LoopIncrement != null)
{
CancelEventArgs args = new CancelEventArgs();
LoopIncrement(null, args);
if (args.Cancel)
{
break;
}
}
}
And then elsewhere:
myObj.LoopIncrement += MyHandler;
private void MyHandler(object sender, CancelEventArgs e)
{
if(someCondition)
{
e.Cancel = true;
}
}
This way you can somewhat control the loop from outside....
Have the condition in a locked property.
private Boolean BreakCondition
{
get { lock(_LockObject) { return _BreakCondition; } }
set { lock(_LockObject) { _BreakCondition = value; } }
}
private Boolean _BreakCondition = false;
private Object _LockObject = new Object();
if (this.BreakCondition)
{
break;
}
How about using iterators, and yield magic to solve the problem.
Here is an article on infinite lists that might be useful
http://www.codethinked.com/post/2009/02/04/Infinite-Lists-With-C-Yield.aspx
class Program
{
static void Main(string[] args)
{
Predicate<int> when = i => i > 100 && Console.ReadKey().KeyChar.ToString() == "0";
foreach(var i in Numbers().BreakOn(when))
{
Console.WriteLine(i);
}
Console.ReadLine();
}
private static IEnumerable<int> Numbers()
{
var i = 0;
while(true)
{
yield return i++;
}
}
}
public static class Util
{
public static IEnumerable<int> BreakOn(this IEnumerable<int> sequence, Predicate<int> when)
{
foreach(int i in sequence)
{
if(when(i))
{
yield break;
}
yield return i;
}
}
}
I think you can use flag
bool stop = false;
for(int i=0;i<num;i++)
{
if(stop) break;
}
The short answer is: no. If you don't control the code, then you can't cause the loop to terminate.
If you do control the code, you could build in some sort of cooperation, but it sounds messy. Maybe you can elaborate on why?

Categories

Resources