C# 替换方法的所有用法(引入间接寻址)
我通常不太喜欢重构工具。无需详细说明。不过,我偶尔也会尝试新版本。以下是我在评估resharper 4.5时试图做的事情: 我需要用要创建的包装器方法替换方法的所有用法,但我不能。我通常很难注意到一个明显的特征,是这样吗?如果resharper没有此功能,您知道此类工具吗 编辑2:已改进示例,以包括实例方法调用。 编辑: 下面是一个简单的例子C# 替换方法的所有用法(引入间接寻址),c#,refactoring,resharper,C#,Refactoring,Resharper,我通常不太喜欢重构工具。无需详细说明。不过,我偶尔也会尝试新版本。以下是我在评估resharper 4.5时试图做的事情: 我需要用要创建的包装器方法替换方法的所有用法,但我不能。我通常很难注意到一个明显的特征,是这样吗?如果resharper没有此功能,您知道此类工具吗 编辑2:已改进示例,以包括实例方法调用。 编辑: 下面是一个简单的例子 static void Main(string[] args) { while(true) {
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;
}
我需要的是:Edit2:添加了一个实例示例
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);
}
控制台。嘟嘟声呼叫被重构。接下来让我们重构StringBuilder.Appendchar:
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));
}
}
从用法中选择并可能省略公共参数(如250以上)或非扩展静态的公共实例参数将使此功能更有价值。希望这能澄清问题。它没有包含在任何.NET重构IIRC中,具有这种重构的工具是Eclipse,但对于.NET/C则不是。假设包装器方法在同一个类中,您可以在Resharper中将当前方法重命名为新包装器方法的名称ctrl+R+R。这也将重命名解决方案中对此方法的所有调用。然后手动重新命名原始方法,不要使用Resharper,否则所有调用也会重新命名,并添加包装器方法 基于您的编辑,我认为您将不太幸运地从任何VisualStudio加载项中获得所需的功能,我已经看到了这些功能,而不仅仅是简单的查找和替换,我想这将为您提供一些方法
取决于您愿意为此投入多少时间和精力,我认为可以使用该框架并编写一个插件来执行这种重构。ReSharper没有将此作为一个单独的重构。我可以这样做: 选择要包装的方法的内容,并使用Extract方法从内容中创建新的私有方法。 原来的方法现在是一个简单的包装器。如果您愿意,可以重命名它,或者根据您的喜好对其进行操作,使其成为静态的,移动到不同的类,使用try/catch进行包围,等等。 编辑: 根据您的编辑,您似乎还有一个问题。不仅是Console.Beep不在同一个类中,甚至不在您的类中 但如果您不介意进行一些搜索和替换,那么您可以将其放入自己的类中,然后继续重构:
namespace Temporary {
public class Console {
public static void Beep(int x, int y) {System.Console.Beep(x,y);}
}
}
然后在文件中执行替换以替换Console.Beep和Temporary.Console.Beep,并按上述步骤进行操作。Resharper有一个功能。它可以搜索和替换模式和表达式
这将重构对Console的所有调用。点击您自己的方法。仅当250是第一个参数时,它才替换用法:
但是,这将取代在您自己的Beep方法中使用Console.Beep。您必须手动替换该用法。我通常就是这样做的。很好用!如果在同一个类中,在我的情况下,包装器不仅会在不同的类中,而且会在不同的程序集中。正如您所提到的,这是重构一个方法和重命名其用法,这是两件不同的事情。我需要重构它的用法。不过,谢谢,我应该看到它的到来。这至少证实了我并不孤单。谢谢。你能给我举一个Eclipse执行此操作的示例吗?我想看看它是如何处理将所有引用从一种对象类型更改为另一种对象类型的需求的,在Eclipse中称为“引入间接寻址”。在Eclipse中,主要是在一段单独的代码中实现每个重构。这不一定是真的,见Jeroen v/d Bos关于这个的硕士论文:homepages.cwi.nl/~paulk/thessesmastersoftwareengineering/2008/JeroenVanDenBos.pdf我只是在考虑它的命名。引入间接法肯定是对它的总结。令人惊讶的是,这项功能自2006年以来就已经存在,而且没有类似的功能。再次感谢你提供的信息。不知道谁会投票否决你的答案。答案不一定总是直接和完整的。希望有人不要标记你的评论。这只适用于静态函数,需要谨慎处理。不过谢谢。如果问题是怎么做而不是有没有这样的功能,我的朋友建议扩展方法应该像你描述的那样工作。当然,这两种方法并不总是有效的,你需要一点运气,这是我所缺乏的。@orca:我不认为这会局限于静态方法。将提取的方法移动到另一个类将要求它成为静态的,但包装器方法不需要更改。此外,谨慎的过程并不是真正必要的。任何失败都可能会破坏生成,因此请在签入之前进行生成。如果使用解决方案范围的分析,ReSharper会告诉您是否有任何问题。这并不假设所有受影响的代码都是
在同一个解决方案中,至少是暂时的。假设我们有多个控制台,并调用像console1.Beep。。。还有控制台2.嘟嘟。。。。由于Beep不是静态的,所以很难找到它的用法。更不用说重载之类的了。即使是静态的情况也有问题。现在,假设还有一个控制台。Beepint,int,int,这可能很麻烦。甚至是存在Virtual.Console.Beepint,int甚至不会破坏构建的危险情况。或者类似的原因,为什么“查找用法/引用”功能首先存在。这无关紧要。它仍然有效,ReSharper中的Find Usages命令无论如何都会找到所有用法。在这种情况下,您甚至不需要查找和替换。这是因为Console.Beep==System.Console.Beep,您无法更改它。