我经常需要使用支持字段将自动属性转换为完整属性,以便我可以实现INotifyPropertyChanged
。当一个班级有50多个属性时,它变得非常繁琐。
public string MyProperty { get; set;}
到
private string _myProperty;
public string MyProperty
{
get
{
return _myProperty;
}
set
{
_myProperty = value;
OnPropertyChanged("MyProperty");
}
}
我能够创建一个以上述格式创建新属性的代码段,但我不知道是否可以提取现有属性的名称和类型并替换它。
我看到了kindofmagic,但我真的不想在我的项目中使用奥术魔法。
This question解释了如何在Resharper中做到这一点,但我没有Resharper。我甚至下载了试用版,但仍然无法弄清楚如何做到这一点。
有没有办法用代码片段,宏,甚至免费扩展来做到这一点?看起来它应该相当简单。
答案 0 :(得分:8)
如果你有notepad ++,你可以通过RegEx来做(非常难看,但有效)
找到:(public)\s+([a-zA-z0-9]+)\s+([a-zA-z0-9]+)\s*\{\s*+get;\s*set;\s*\}
替换为:private \2 _\3\; \r\n \1 \2 \3 \r\n \{ \r\n get \{ return _\3\; \} \r\n set \{ _\3=value\; OnPropertyChanged\(\"\3\"\)\; \} \r\n \}
确保选中“正则表达式”
这就是“查找/替换”屏幕的样子:
它来自
要:
编辑:感谢Britton,这是Visual Studio的等价物:
查找:public[^\S\r\n](.+)[^\S\r\n](\b(_\w+|[\w-[0-9_]]\w*)\b)[^\S\r\n]{[^\S\r\n]get;[^\S\r\n]set;[^\S\r\n]}
替换:private $1 _$2;\r\npublic $1 $2 {\r\nget\r\n{\r\nreturn _$2;\r\n}\r\nset\r\n{\r\n_$2 = value; OnPropertyChanged("$2");\r\n}\r\n}
答案 1 :(得分:3)
我最终使用Dan's regex一次转换了许多属性。我还发现了一个名为PropMan的Visual Studio扩展,它适用于一次转换单个属性。只需将光标放在属性上,然后点击Ctrl+\, Ctrl+\
即可在auto / full。之间进行转换。
答案 2 :(得分:2)
不幸的是,看起来Visual Studio中不支持这些类型的自定义重构代码段。浏览文档,我发现this:
SurroundsWith:允许将代码段放在选定的周围 一段代码。
扩展:允许在光标处插入代码段。
重构:指定在Visual C#期间使用代码段 重构。 重构不能用于自定义代码段。
我还继续创建了一个从头开始创建完整属性的代码段,但它仅适用于新属性,而不是现有属性。
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets
xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>fprop</Title>
<Shortcut>fprop</Shortcut>
<Description>Full Property with Backing Store</Description>
<Author>Nathan McGinn</Author>
<SnippetTypes>
<SnippetType>Refactoring</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<Default>string</Default>
<ToolTip>The type of your property</ToolTip>
</Literal>
<Literal>
<ID>back</ID>
<Default>_myProperty</Default>
<ToolTip>The name of your backing variable</ToolTip>
</Literal>
<Literal>
<ID>prop</ID>
<Default>MyProperty</Default>
<ToolTip>Your public property's name</ToolTip>
</Literal>
</Declarations>
<Code Language="CSharp">
<![CDATA[private $type$ $back$;
public $type$ $prop$
{
get
{
return this.$back$;
}
set
{
this.$back$ = value;
OnPropertyChanged("$prop$");
}
}]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
我认为,就片段而言,Visual Studio扩展将需要重构现有代码(或Dan建议的正则表达式查找/替换)。
答案 3 :(得分:1)
我仅使用class1
测试了此代码。但是,它会给你起点。我没有使用花哨的命名变量。请根据需要更改变量名称。它会将private...
放在属性前面并忽略方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public class Class1
{
public int Val
{
get;
set;
}
public int Val1
{
get;
set;
}
public void M1() { }
}
}
更改上述类的代码
public class Program
{
public static void Main(string[] args)
{
Class1 c = new Class1();
Type testType = c.GetType();
PropertyInfo[] prinfo = testType.GetProperties();
string[] filetest=File.ReadAllLines("Class1.cs"); //put correct file path here
int index=0,i=0;
foreach (PropertyInfo p in prinfo)
{
while(i < filetest.Length )
{
index = filetest[i].IndexOf(p.Name);
if (index > 0)
{
index = 0;
filetest[i]=filetest[i].Insert(0, "private " + p.PropertyType.ToString() + " _" + p.Name+";" + Environment.NewLine);
}
i++;
}
}
File.WriteAllLines("Class1.cs", filetest);//put correct file path here
Console.Read();
}
}