以特定方式访问属性的 FxCop 规则



我有一个 Item 类(我无法访问它),它有两种不同的方法来访问 Item 的字段。我想要一个自定义的 FxCop 规则,它更喜欢一个而不是另一个。

我可以通过拥有一个项目并直接访问item["fieldname"]来从特定字段中获取值,这将返回一个字符串。
这个代码:

public string this[string fieldName]
{
get
{
Assert.ArgumentNotNullOrEmpty(fieldName, "fieldName");
ID result;
if (ID.TryParse(fieldName, out result))
return this[result];
if ((int) fieldName[0] == 64)
return this.Fields.GetSpecialField(fieldName);
Field field = this.Fields[fieldName];
if (field == null)
return "";
else
return field.Value;
}
set
{
Assert.ArgumentNotNullOrEmpty(fieldName, "fieldName");
ID result;
if (ID.TryParse(fieldName, out result))
{
this[result] = value;
}
else
{
Field field = this.Fields[fieldName];
if (field == null)
return;
field.Value = value;
}
}
}
public string this[int index]
{
get
{
Field field = this.Fields[index];
if (field == null)
return "";
else
return field.Value;
}
set
{
Field field = this.Fields[index];
if (field == null)
return;
field.Value = value;
}
}
public string this[ID fieldID]
{
get
{
Assert.ArgumentNotNull((object) fieldID, "fieldID");
return this.Fields[fieldID].Value;
}
set
{
Assert.ArgumentNotNull((object) fieldID, "fieldID");
this.Fields[fieldID].Value = value;
}
}

或者,我可以像这样访问 Field 属性:item.Fields["Fieldname"].Value.
替代代码:

public Field this[ID fieldID]
{
get
{
return new Field(fieldID, this._ownerItem);
}
}
public Field this[string fieldName]
{
get
{
ID fieldId = TemplateManager.GetFieldId(fieldName, this.TemplateId, this.Database);
if (fieldId == null)
return (Field) null;
else
return this[fieldId];
}
}
public Field this[int index]
{
get
{
Field[] fields = this.GetFields();
if (index < fields.Length && index >= 0)
return fields[index];
else
return (Field) null;
}
}

这种方法可能会抛出NullReferenceException,例如,如果字段名拼写错误。然后Field对象将被null,因此无法检索值。

现在,由于第一种方法更安全,我想在使用第二种方法时发出警告。我发现我需要使用

public override ProblemCollection Check(Member member)
{
} 

方法,然后将成员强制转换为Microsoft.FxCop.Sdk.PropertyNode。但是,从那里开始,我不知道该怎么做,特别是因为它们在末尾使用相同的代码(第一个选项调用第二个选项,但如果字段名称拼写错误并且字段为空,则第一个选项将只返回一个空字符串)。

或者,如果这是不可能的,我想给出一个 FxCop 错误,如果使用第二个选项而不检查字段的空值。

一些管理细节:我正在使用Visual Studio 2012和FxCop 10。

编辑
为了进一步澄清,此规则不应检查属性本身(即类似于Naming.IdentifiersShouldBeCasedCorrectly),而应检查如何从代码中的其他地方调用它们。

由于您正在查看如何在代码中的其他地方使用这些属性,因此您需要使用BaseIntrospectionRule的访问者模式支持来查找对有问题的属性的引用。

只有分析程序集的内容才会传递给Check,因此,如果仅引用而不是分析包含ItemFieldsCollection的程序集,则Item索引器不应导致问题。

在不深入研究数据流分析(这在很大程度上超出了 Introspector 的范围)的情况下,您可以通过运行访问者遍历所有分析的方法主体并标记Field.Valuegetter 的调用来获得非常粗略的近似:

public override ProblemCollection Check(Member member)
{
var method = member as Method;
if (method != null)
{
VisitStatements(method.Body.Statements);
}
return Problems;
}
public override void VisitMethodCall(MethodCall methodCall)
{
var memberBinding = methodCall.Callee as MemberBinding;
if (memberBinding != null)
{
var methodCalled = memberBinding.BoundMember as Method;
if (methodCalled != null)
{
if (methodCalled.FullName == "Some.Namespace.Field.get_Value")
Problems.Add(new Problem(GetResolution(), methodCall));
}
}
base.VisitMethodCall(methodCall);
}

更好的近似也会遍历到MethodCall的第零Operand,只有当该Operand是对FieldsCollection索引器的调用时,才会引发问题。

为什么不使用 de ObsoleteAttribute?

相关内容

  • 没有找到相关文章

最新更新