我想要一些技术来自动替换以下代码:
[WarnIfGetButUninitialized]
public int MyProperty {get; set; }
有了这个:
/// <summary>
/// Property which warns you if its value is fetched before it has been specifically instantiated.
/// </summary>
private bool backingFieldIsPopulated = false;
private int backingField;
public int MyProperty {
get
{
if (backingFieldIsPopulated == false)
{
Console.WriteLine("Error: cannot fetch property before it has been initialized properly.\n");
return 0;
}
return backingField;
}
set {
backingField = value;
backingFieldIsPopulated = true;
}
}
我更喜欢在编译时工作的解决方案,因为反射很慢。
我知道面向方面编程(AOP)会这样做(例如PostSharp和CciSharp),但是如果有任何其他方法可以实现这一点,我会感兴趣。
更新
请参阅How to use PostSharp to warn if a property is accessed before it has been initialized?,其中包含指向使用PostSharp演示该技术的示例代码的链接。
答案 0 :(得分:2)
属性只是将元数据添加到类和类成员 - 他们自己什么都不做。
在装饰成员上完成的操作是通过反射完成的 - 在一些现有工具中有一些支持,但是对自定义属性没有这样的支持。
简而言之 - 如果编译器尚未支持,则无法在编译时检查属性。
但是,您可以创建自己的code snippets,以便更轻松地编写和创建此类代码。
答案 1 :(得分:0)
T4模板可用于代码生成。没有实现我自己,但T4模板用于在C#中生成代码。更多信息来自scott hanselman
答案 2 :(得分:0)
仅通过编译检查某些属性。 ObsoleteAttribute和ConditionalAttribute是其中两个。 使用Resharper,您可以获得此类警告。我不知道任何其他可以做到这一点的工具。
答案 3 :(得分:0)
您可以执行类似于.NET的Lazy的实现,但是在使用该属性时需要更多的单词。像这样的非线程安全示例:
public class WarnIfGetButUninitialized<T>
{
T _property;
public T Value
{
get
{
if(_property == null)
{
Console.WriteLine("Error: cannot fetch property before it has been initialized properly.\n");
return default(T);
}
return _property;
}
set { _property = value; }
}
}
答案 4 :(得分:0)
来自Gael Fraiteur的PostSharp论坛(感谢Gael!):
您必须使用实现的LocationInterceptionAspect IInstanceScopedAspect。字段'backingFieldIsPopulated'成为 方面的领域。
您可以在此示例中找到灵感: