检查是否已使用具有相同值的属性
Check if Attribut with same value is already used
我正在写一种TLV de-/serialization class.
与 protobuf-net 一样,我有一个 classes 的合同属性和一个属性的成员属性。成员属性有一个标签号,就像在 protobuf 中一样。
现在我想检查标签号是否已被使用,最好的解决方案是是否存在某种编译器错误。如果这有帮助,我也有 postsharp。
class 结构如下所示:
[TlvContract]
public class Person{
[TlvMember(1)]
public String Name{get; set;}
[TlvMember(2)]
public Int32 ID{get; set;}
// This should create a warning or compile error!!!!
[TlvMember(1)]
public String Town{get; set;}
}
除了 Roslyn 分析器之外,PostSharp 是一种可行的方法。
以下是此类检查和错误输出的基本实现:
[MulticastAttributeUsage(PersistMetaData = true)]
public class TlvContractAttribute : TypeLevelAspect
{
public override void CompileTimeInitialize(Type target, AspectInfo aspectInfo)
{
Dictionary<int, PropertyInfo> indexes = new Dictionary<int, PropertyInfo>();
foreach (PropertyInfo propertyInfo in target.GetProperties())
{
TlvMemberAttribute memberAttr =
propertyInfo.GetCustomAttributes()
.Where(x => x is TlvMemberAttribute)
.Cast<TlvMemberAttribute>()
.SingleOrDefault();
if (memberAttr == null)
{
Message.Write(MessageLocation.Of(propertyInfo), SeverityType.Error, "USR001",
"Property {0} should be marked by TlvMemberAttribute.", propertyInfo);
continue;
}
if (indexes.ContainsKey(memberAttr.Index))
{
Message.Write(MessageLocation.Of(propertyInfo), SeverityType.Error, "USR002",
"Property {0} marked by TlvMemberAttribute uses Index {1}, which is already used by property {2}.",
propertyInfo, memberAttr.Index, indexes[memberAttr.Index]);
continue;
}
indexes[memberAttr.Index] = propertyInfo;
}
}
}
它在您定义它的程序集中工作。您只需要确保 PostSharp 实际上在您希望检查工作的所有程序集上运行。
如果您的属性需要不同的基础 class,您还可以实现 ITypeLevelAspect
和 ITypeLevelAspectBuildSemantics
接口。
我正在写一种TLV de-/serialization class.
与 protobuf-net 一样,我有一个 classes 的合同属性和一个属性的成员属性。成员属性有一个标签号,就像在 protobuf 中一样。 现在我想检查标签号是否已被使用,最好的解决方案是是否存在某种编译器错误。如果这有帮助,我也有 postsharp。 class 结构如下所示:
[TlvContract]
public class Person{
[TlvMember(1)]
public String Name{get; set;}
[TlvMember(2)]
public Int32 ID{get; set;}
// This should create a warning or compile error!!!!
[TlvMember(1)]
public String Town{get; set;}
}
除了 Roslyn 分析器之外,PostSharp 是一种可行的方法。
以下是此类检查和错误输出的基本实现:
[MulticastAttributeUsage(PersistMetaData = true)]
public class TlvContractAttribute : TypeLevelAspect
{
public override void CompileTimeInitialize(Type target, AspectInfo aspectInfo)
{
Dictionary<int, PropertyInfo> indexes = new Dictionary<int, PropertyInfo>();
foreach (PropertyInfo propertyInfo in target.GetProperties())
{
TlvMemberAttribute memberAttr =
propertyInfo.GetCustomAttributes()
.Where(x => x is TlvMemberAttribute)
.Cast<TlvMemberAttribute>()
.SingleOrDefault();
if (memberAttr == null)
{
Message.Write(MessageLocation.Of(propertyInfo), SeverityType.Error, "USR001",
"Property {0} should be marked by TlvMemberAttribute.", propertyInfo);
continue;
}
if (indexes.ContainsKey(memberAttr.Index))
{
Message.Write(MessageLocation.Of(propertyInfo), SeverityType.Error, "USR002",
"Property {0} marked by TlvMemberAttribute uses Index {1}, which is already used by property {2}.",
propertyInfo, memberAttr.Index, indexes[memberAttr.Index]);
continue;
}
indexes[memberAttr.Index] = propertyInfo;
}
}
}
它在您定义它的程序集中工作。您只需要确保 PostSharp 实际上在您希望检查工作的所有程序集上运行。
如果您的属性需要不同的基础 class,您还可以实现 ITypeLevelAspect
和 ITypeLevelAspectBuildSemantics
接口。