我们有旧代码,其中人们已经编写了针对自定义私有变量的属性,这些变量可以转换为自动属性(public Foo {get; set;})。我怎么能发现这个?
答案 0 :(得分:1)
要编写这样的规则,您需要以某种方式加入相应的属性访问器和字段。我可以想象两种方法:
您可以检查getter / setter正在读取哪个属性/指定哪个字段(只有一个字段)
您可以在字段和属性的名称上定义模式(例如,每个字段名称都以两个字符作为前缀, Foo 属性对应于 m_Foo 字段)
第一条规则可能如下:
// <Name>Use Automatic Property</Name>
warnif count > 0
from t in Application.Types
from f in t.Fields
where !f.Name.Contains('<') // Eliminate generated by compiler fields
let getter = (from m in t.Methods
where m.IsPropertyGetter &&
m.FieldsReadButNotAssigned.Contains(f) &&
m.FieldsUsed.Count() == 1
select m)
let setter = (from m in t.Methods
where m.IsPropertySetter &&
m.FieldsAssigned.Contains(f) &&
m.FieldsUsed.Count() == 1
select m)
where getter.Count() > 0 || setter.Count() > 0
select new { f, getter, setter }
第二条规则可能如下:
// <Name>Use Automatic Property</Name>
warnif count > 0
from t in Application.Types
from f in t.Fields
where !f.Name.Contains('<') // Eliminate generated by compiler fields
// Here we consider that field name is prefixed with two any characters
where f.Name.Length > 2
let name = f.Name.Substring(2, f.Name.Length -2)
let getter = (from m in t.Methods
where m.IsPropertyGetter &&
m.SimpleName == "get_" + name
select m).SingleOrDefault()
let setter = (from m in t.Methods
where m.IsPropertySetter &&
m.SimpleName == "set_" + name
select m).SingleOrDefault()
where getter != null || setter != null
select new { f, getter, setter }
虽然第二条规则可能会遗漏一些积极因素,但第一条规则将返回许多误报。也许我们可以编写两者的混合(名称上的模式,如属性名称包含部分字段名称)。