Does someone know a c# tool that could extract all code in given class from methods?
Example starting file:
public class HelloWorld
{
public static void Main()
{
Print("Hello, ");
Print("World");
PrintExclamationMark();
}
private static void Print(string text)
{
System.Console.WriteLine(text);
}
private static void PrintExclamationMark();
{
System.Console.WriteLine("!");
}
}
Result I would like to get after using the tool on given class/file:
public class HelloWorld
{
public static void Main()
{
System.Console.WriteLine("Hello, ");
System.Console.WriteLine("World");
System.Console.WriteLine("!");
}
}
Such tool could be very helpful when I extracting a lot of new methods and double checking if no code was omitted.
Related
Consider the following console program. It has four classes: Program, Attacker, Defender, and Helper. I want to remove the logic from the Defender class and use delegates to call helpers. I've spent some time on this and can't quite get it.
Where do I declare my delegate: in Program or in Defender?
Where do I instantiate my delegate: in Program or in Defender?
Where do I subscribe my delegate: in Program or in Helper?
I could post my attempts but it wouldn't be helpful.
using System;
namespace Delegates19
{
public class Program
{
static void Main(string[] args)
{
Attacker a = new Attacker();
string weapon = "sword";
a.Attack(weapon);
Defender d = new Defender();
d.Help(weapon);
weapon = "spear";
a.Attack(weapon);
d.Help(weapon);
}
}
public class Attacker
{
public void Attack(string s)
{
Console.WriteLine($"Attacker attacks with {s}");
}
}
public class Defender
{
public void Help(string s)
{
Console.WriteLine($"Defender is attacked with {s} and calls for help");
if (s == "sword")
Helper.Knight();
if (s == "spear")
Helper.Bowman();
}
}
public class Helper
{
public static void Knight()
{
Console.WriteLine($"Knight charges Attacker");
}
public static void Bowman()
{
Console.WriteLine($"Bowman shoots Attacker");
}
}
}
I'm really not sure why you would want to do this, but these both work and might give you ideas.
Unless I understand your need for events/delegates I actually prefer your code over these.
Delegates:
public class Defender
{
private static Action SwordAction = Helper.Knight;
private static Action SpearAction = Helper.Bowman;
public void Help(string s)
{
Console.WriteLine($"Defender is attacked with {s} and calls for help");
if (s == "sword")
SwordAction();
if (s == "spear")
SpearAction();
}
}
public static class Helper
{
public static void Knight()
{
Console.WriteLine($"Knight charges Attacker");
}
public static void Bowman()
{
Console.WriteLine($"Bowman shoots Attacker");
}
}
Events:
static void Main(string[] args)
{
using (var d = new Defender())
{
d.GetHelp += StandardDefenseHelp.Defender_GetHelp;
d.Help("sword");
d.Help("spear");
}
}
public class Defender : IDisposable
{
public event EventHandler<string> GetHelp;
private void RaiseGetHelp(string weapon) => GetHelp?.Invoke(this, weapon);
public void Help(string weapon)
{
Console.WriteLine($"Defender is attacked with {weapon} and calls for help");
RaiseGetHelp(weapon);
}
public void Dispose()
{
GetHelp = null;
}
}
public static class StandardDefenseHelp
{
public static void Defender_GetHelp(object sender, string weapon)
{
if (weapon == "sword")
Knight();
if (weapon == "spear")
Bowman();
}
private static void Knight()
{
Console.WriteLine($"Knight charges Attacker");
}
private static void Bowman()
{
Console.WriteLine($"Bowman shoots Attacker");
}
}
Important: events often are the cause of memory leaks, that's why Defender is now disposable.
The above design could be useful if you have multiple "DefenseHelp" types and other things also should happen when a defender needs help that the defender itself needs to know nothing about.
But I'd only do this if it gave some benefit. I believe in the KISS development methodology.
In C# , in Visual Studio, using a Console Application, is there a way to make methods in a class and call them in main program using readline?
Aka, a way to choose which methods to open when the program is running.
Easiest way is a switch statement for <4 cases, and a Dictionary for 4 or more cases.
class Program
{
private static IDictionary<string, Action> MethodMappings = new Dictionary<string, Action> {
{"Method1", Method1},
{"Method2", Method2},
...
}
public static void Main(string[] args) {
var methodCall = Console.ReadLine();
if (!MethodMappings.ContainsKey(methodCall)) {
//unrecognized command
}
MethodMappings[methodCall].Invoke();
}
private static void Method1() { ... }
private static void Method2() { ... }
}
This is very much possible using Reflection. Here is sample code to help you out:
class Program
{
public static void Hello1()
{
Console.WriteLine("\nHello 1");
}
public static void Hello2()
{
Console.WriteLine("\nHello 2");
}
static void Main(string[] args)
{
while (true)
{
String method = Console.ReadLine();
Type methodType = typeof(Program);
MethodInfo voidMethodInfo = methodType.GetMethod(method);
voidMethodInfo.Invoke(method,null);
}
}
}
For more information you can visit here.
Asking the same question as
Using delegates with non static methods [no picked answer]
so as to bring a closure to it.
So I use #Adam Marshall's solution, it works, but as soon as I start using it, i.e., Testit():
using System;
public class TestClass
{
private delegate void TestDelegate();
TestDelegate testDelegate;
public TestClass()
{
testDelegate = new TestDelegate(MyMethod);
}
public static void Testit()
{
testDelegate();
}
private virtual void MyMethod()
{
Console.WriteLine("Foobar");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
TestClass.Testit();
}
}
It started to give the followig Error:
A object reference is required for the non-static field, method, or property
You can test it out here .
How to fix it? (Please fix it if possible instead of directing me to other posts, I've read them but am not able to understand them) Thx.
Either everything has to be static or everything has to be instance. You're getting in trouble because you are mixing and matching.
Everything static:
using System;
public class TestClass
{
private delegate void TestDelegate();
static TestDelegate testDelegate; //<-- static
static TestClass() //<-- static
{
testDelegate = new TestDelegate(MyMethod);
}
public static void Testit()
{
testDelegate();
}
private static void MyMethod()
{
Console.WriteLine("Foobar");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
TestClass.Testit();
}
}
Everything instanced:
using System;
public class TestClass
{
private delegate void TestDelegate();
TestDelegate testDelegate;
public TestClass()
{
testDelegate = new TestDelegate(MyMethod);
}
public void Testit()
{
testDelegate();
}
private void MyMethod()
{
Console.WriteLine("Foobar");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
var t = new TestClass();
t.Testit(); //<-- non-static
}
}
Output (same in both examples):
Hello World
Foobar
You could use action C# internal delegate. This way you do not have specify the delegate. Then in your static method you could new up your object.
using System;
public class TestClass
{
Action testDelegate;
public TestClass()
{
testDelegate = new Action(MyMethod);
}
public static void Testit()
{
TestClass ts = new TestClass();
ts.testDelegate();
}
private void MyMethod()
{
Console.WriteLine("Foobar");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
TestClass.Testit();
}
}
Output:
Hello World
Foobar
Assume I have a code:
class Module1 {
public static void Main(string[] args) {
Module1.level1();
}
public static void level1() {
Module1.level2();
}
public static void level2() {
Module2.level1();
}
}
[DetectWhenFlowExitsClass] // <-- note aspect
class Module2 {
public static void level1() {
Module2.level2();
}
public static void level2() {
Module2.level3();
}
public static void level3() {
throw new SystemException("oops");
}
}
After calling Main() I get a stacktrace:
Unhandled Exception: System.SystemException: oops
at Test.Module2.level3()
at Test.Module2.level2()
at Test.Module2.level1()
at Test.Module1.level2()
at Test.Module1.level1()
at Test.Module1.Main(String[] args)
Question
How to write aspect which detects moment when "control flow" exits code of class Module2?
That is, when Test.Module2.level1() finishes its work [here, due to exception].
Exist any shortcuts for this in PostSharp?
The most basic way would be to use OnMethodBoundaryAspect, which allows you to handle the method entry and method exit advices. You will need to count number of method of each particular class on the stack and when this count goes from 1 to 0, the control is leaving methods of the aspected class.
Here is the sample aspect code:
[Serializable]
public class DetectWhenFlowExitsClass : OnMethodBoundaryAspect
{
[ThreadStatic] private static Dictionary<Type, int> stackCounters;
private Type declaringType;
public override bool CompileTimeValidate(MethodBase method)
{
declaringType = method.DeclaringType;
return true;
}
private void EnsureStackCounters()
{
if (stackCounters == null)
stackCounters = new Dictionary<Type, int>();
}
public override void OnEntry(MethodExecutionArgs args)
{
EnsureStackCounters();
int counter;
stackCounters.TryGetValue(declaringType, out counter);
stackCounters[declaringType] = ++counter;
}
public override void OnExit(MethodExecutionArgs args)
{
EnsureStackCounters();
int counter;
stackCounters.TryGetValue(declaringType, out counter);
stackCounters[declaringType] = --counter;
if (counter == 0)
Console.WriteLine("Control leaving class {0}", declaringType.Name);
}
}
You will probably need to tinker with this aspect implementation a bit, but it works in basic situations.
Is it by any chance possible to call a method without referencing to its class?
For instance, you have a helper class:
class HelperTools
{
public static void DoWork()
{ /*...*/ }
}
And then you need to call it:
class MainClass
{
public static void Main()
{
HelperTools.DoWork();
}
}
Is it possible to call DoWork(); without a reference? Like this:
public static void Main()
{
DoWork();
}
Just for sake of simplicity.
Not quite, but here are 5 patterns that get you close:
namespace My.Namespace
{
using H = MyHelperClass;
public class MyHelperClass
{
public static void HelperFunc1()
{
Console.WriteLine("Here's your help!");
}
}
public class MyHelperClass2
{
public static void HelperFunc4()
{
Console.WriteLine("Here's your help!");
}
}
public interface IHelper{ }
public static class HelperExtensions
{
public static void HelperFunc3(this IHelper self)
{
Console.WriteLine("Here's your help!");
}
}
public class MyClass : MyHelperClass2, IHelper
{
private static readonly Action HelperFunc2 = MyHelperClass.HelperFunc1;
private static void HelperFunc5()
{
Console.WriteLine("Here's your help!");
}
public void MyFunction()
{
//Method 1 use an alias to make your helper class name shorter
H.HelperFunc1();
//Method 2 use a class property
HelperFunc2();
//Method 3 extend an interface that has extension methods.
//Note: you'll have to use the this keyword when calling extension
this.HelperFunc3();
//Method 4 you have access to methods on classes that you extend.
HelperFunc4();
//Method 5 put the helper method in your class
HelperFunc5();
}
}
}
No. Java has the concept of importing static like this, but C# does not. (IMO, a naked DoWork() without any clue as to where the implementation resides is non-ideal.)
a few years late but maybe this will help someone else...
Use a using static directive to reference the static class: (introduced in C# 6)
using static HelperTools;
class MainClass
{
public static void Main()
{
DoWork();
}
}
---------------- HelperTools.cs--------------------
class HelperTools
{
public static void DoWork()
{ /*...*/ }
}
The only place you can call DoWork from without referencing the class name is within the class itself. For instance, if you add a non-static method to HelperTools:
public void foo()
{
DoWork();
}
You can call DoWork from within it, even though foo() is not static.