关于c#:最有用的属性

Most Useful Attributes

我知道属性非常有用。有一些预定义的属性,如[Browsable(false)],允许您在"属性"选项卡中隐藏属性。下面是一个解释属性的好问题:.NET中的属性是什么?

您在项目中实际使用的预定义属性(及其命名空间)是什么?


当你在解析过程中小鼠在该类型的装置上时,可以很快地看到一种类型的定制输出。Example:

1
2
3
4
5
6
[DebuggerDisplay("FirstName={FirstName}, LastName={LastName}")]
class Customer
{
    public string FirstName;
    public string LastName;
}

This is how it should look in the debuger:

MGX1〔0〕

此外,还值得一提的是,[WebMethod]属性与CacheDuration属性集可以避免不需要执行网络服务方法。


在我看来,这是框架中最常用的属性之一。能够发出警告的代码不应使用长时间,这是非常有用的。我爱有一种方式告诉发展中世界,任何东西都不应该被使用,就像有一种方式来解释为什么和点,更好/新的方式去做一些事情。

这是一个很漂亮的动作工具。它允许你将方法添加到你的代码中,以便在你建立释放的解决方案时无法编译出来。

然后,在网上有许多特殊的属性,我发现这些属性是有用的,但这些属性更为具体,在我发现的服务器控制的开发之外没有任何用途。


漂亮的手。句法糖要有把握,但还是很好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Flags]
enum SandwichStuff
{
   Cheese = 1,
   Pickles = 2,
   Chips = 4,
   Ham = 8,
   Eggs = 16,
   PeanutButter = 32,
   Jam = 64
};

public Sandwich MakeSandwich(SandwichStuff stuff)
{
   Console.WriteLine(stuff.ToString());
   // ...
}

// ...

MakeSandwich(SandwichStuff.Cheese
   | SandwichStuff.Ham
   | SandwichStuff.PeanutButter);
// produces console output:"Cheese, Ham, PeanutButter"

Leppie points out something I had not realized,which rather dampens my enthusiasm for this attribute:i t doesn't instruct the compiler to allow bit combinations as values for enumeration varies for enumeration varies,the compiler allows this for enumerations regardless.我的C+background showing through西格


我喜欢系统诊断。

这是一个很好的方法,可以避免向一条线路的方法或性能转移(如果你被迫在早期工作,但没有自动性能)。把属性放到一个短暂的方法上,或者放到一个物业的接收者或设定者上,当你在解调器中"跳进"时,你会飞得很好。


这是一份所有净属性的清单。这里有很多人。

我不知道任何人的事,但我有一些严肃的RTFM!


我的投票将是支持[Conditional]

1
2
3
4
5
[Conditional("DEBUG")]
public void DebugOnlyFunction()
{
    // your code here
}

您可以使用它添加具有高级调试功能的函数;如Debug.Write,它只在调试版本中调用,因此允许您在程序的主流之外封装复杂的调试逻辑。


我总是使用DisplayNameDescriptionDefaultValue属性来覆盖我的用户控件、自定义控件或我将通过属性网格编辑的任何类的公共属性。.NET属性网格使用这些标记来格式化未设置为默认值的名称、说明面板和粗体值。

1
2
3
4
5
6
7
[DisplayName("Error color")]
[Description("The color used on nodes containing errors.")]
[DefaultValue(Color.Red)]
public Color ErrorColor
{
    ...
}

如果找不到XML注释,我只希望Visual Studio的IntelliSense将Description属性考虑在内。这样可以避免重复同一句话两次。


使用了整段时间来编辑和解析对象,并从外部数据源,如XML或远程服务器。更多关于这里。


在Hofstadian Spirit,The [Attribute]属性非常有用,因为它是你如何创建自己属性的。我使用了界面属性来执行插入系统,加上ENUMS描述,模拟多个调度和其他针织物。


以下是关于internalsVisibleto有趣属性的文章。它基本上模仿C++好友访问功能。它对于单元测试非常方便。


我找到了[DefaultValue]


我建议从努尼特图书馆。

单元测试在您的代码中提供了参考和编纂文献的安全性。


1
[XmlIgnore]

因为这允许您忽略(在任何XML序列化中)"parent"对象,否则在保存时会导致异常。


它的名称不好,在框架中不受支持,不需要参数,但对于不可变类,此属性是一个有用的标记:

1
[ImmutableObject(true)]


我喜欢将[ThreadStatic]属性与基于线程和堆栈的编程结合使用。例如,如果我想要一个我想与调用序列的其余部分共享的值,但是我想在带外(即在调用参数之外)这样做,我可能会采用类似的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MyContextInformation : IDisposable {
    [ThreadStatic] private static MyContextInformation current;

    public static MyContextInformation Current {
        get { return current; }
    }

    private MyContextInformation previous;


    public MyContextInformation(Object myData) {
       this.myData = myData;
       previous = current;
       current = this;
    }

    public void Dispose() {
       current = previous;
    }
}

在稍后的代码中,我可以使用它向代码下游的人提供带外上下文信息。例子:

1
2
3
using(new MyContextInformation(someInfoInContext)) {
   ...
}

threadStatic属性允许我只将调用范围限定到有问题的线程,从而避免了跨线程访问数据的混乱问题。


允许避免单步执行不应调试的代码的DebuggerHiddenAttribute。

1
2
3
4
5
6
7
8
9
10
11
public static class CustomDebug
{
    [DebuggerHidden]
    public static void Assert(Boolean condition, Func<Exception> exceptionCreator) { ... }
}

...

// The following assert fails, and because of the attribute the exception is shown at this line
// Isn't affecting the stack trace
CustomDebug.Assert(false, () => new Exception());

此外,它还防止在堆栈跟踪中显示方法,当有一个方法刚刚包装另一个方法时很有用:

1
2
3
4
5
6
7
[DebuggerHidden]
public Element GetElementAt(Vector2 position)
{
    return GetElementAt(position.X, position.Y);
}

public Element GetElementAt(Single x, Single y) { ... }

如果现在调用GetElementAt(new Vector2(10, 10)),并且包装方法发生错误,则调用堆栈不会显示调用引发错误的方法的方法。


DesignerSerializationVisibilityAttribute非常有用。当您将运行时属性放在控件或组件上,并且不希望设计器对其进行序列化时,可以这样使用它:

1
2
3
4
5
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
    get { return baz; }
    set { baz = value; }
}


只有少数属性得到编译器的支持,但是属性的一个非常有趣的用法是在AOP中:PostSharp使用您定制的属性将IL注入方法中,允许各种各样的能力…日志/跟踪只是一个很普通的例子——但是其他一些很好的例子是自动inotifypropertieschanged实现(这里)。

一些直接影响编译器或运行时的事件:

  • [Conditional("FOO")]—只有在构建期间定义了"foo"符号时,才会调用此方法(包括参数计算)。
  • [MethodImpl(...)]—用于表示一些东西,如同步、内联
  • [PrincipalPermission(...)]—用于自动向代码中注入安全检查
  • [TypeForwardedTo(...)]—用于在程序集之间移动类型,而不重建调用方

对于通过反射手动检查的内容,我是System.ComponentModel属性的忠实粉丝;比如[TypeDescriptionProvider(...)][TypeConverter(...)][Editor(...)],它们可以完全改变数据绑定场景中类型的行为(即动态属性等)。


我最近一直在使用[DataObjectMethod]。它描述了方法,这样您就可以将类与ObjectDatasource(或其他控件)一起使用。

1
2
3
4
[DataObjectMethod(DataObjectMethodType.Select)]
[DataObjectMethod(DataObjectMethodType.Delete)]
[DataObjectMethod(DataObjectMethodType.Update)]
[DataObjectMethod(DataObjectMethodType.Insert)]

更多信息


如果我要做一个密码盖,我想这两个最好:

ZZU1


1
[TypeConverter(typeof(ExpandableObjectConverter))]

告诉设计器展开属于(控件的)类的属性

1
[Obfuscation]

指示模糊工具对程序集、类型或成员执行指定的操作。(尽管通常使用的是装配级[assembly:ObfuscateAssemblyAttribute(true)]


在我们当前的项目中,我们使用

1
[ComVisible(false)]

它控制单个托管类型或成员或程序集中所有类型对COM的可访问性。

更多信息


我最常使用的属性是与XML串行相关的属性。

法国电力公司

法国电力公司

法国电力公司

等等

极其有用的时候,任何快捷和肮脏的XML包裹或串行。


成为我喜欢的中间人

允许我隐藏自己的财产,所以UI开发公司不需要拥有他们不需要看到的财产。

有些东西不需要数据。再一次,我们必须完成我们的工作。

我也喜欢劳伦斯·约翰斯顿说过的话。

通常使用的是EDOCX1和EDOCX1。

使用法国电力公司当需要时

走吧我只是认为这些都很有价值。净框架开发人员。


如果项目不在您的解决方案中,[EditorBrowsable(EditorBrowsableState.Never)]允许您隐藏属性和方法,使其不受智能感知的影响。对于隐藏Fluent接口的无效流非常有用。您希望多久获取一次hashcode()或equals()?

对于mvc [ActionName("Name")]允许您使用相同的方法签名进行get操作和post操作,或者在操作名称中使用破折号,否则在没有为其创建路由的情况下是不可能的。


下面是一个快速列表,大致按使用频率排序,列出了我在一个大项目中实际使用的预定义属性(大约500k个loc):

标志、可序列化、WebMethod、ComVisible、TypeConverter、Conditional、ThreadStatic、Obsolete、InternalsVisibleTo、DebuggerStepthrough。


我认为在这里重要的一点是,以下属性也非常重要:

1
STAThreadAttribute

指示应用程序的COM线程模型是单线程单元(STA)。

例如,此属性用于Windows窗体应用程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

而且…

1
SuppressMessageAttribute

禁止报告特定的静态分析工具违反规则,允许对单个代码工件进行多次禁止。

例如:

1
2
3
4
5
6
7
8
[SuppressMessage("Microsoft.Performance","CA1801:ReviewUnusedParameters", MessageId ="isChecked")]
[SuppressMessage("Microsoft.Performance","CA1804:RemoveUnusedLocals", MessageId ="fileIdentifier")]
static void FileNode(string name, bool isChecked)
{
    string fileIdentifier = name;
    string fileName = name;
    string version = String.Empty;
}


[DeploymentItem("myFile1.txt")]关于部署的msdn文档

如果您正在对一个文件进行测试或将该文件用作测试的输入,那么这非常有用。


我通过codesmith生成数据实体类,并为一些验证例程使用属性。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
/// <summary>
/// Firm ID
/// </summary>
[ChineseDescription("送样单位编号")]
[ValidRequired()]
public string FirmGUID
{
    get { return _firmGUID; }
    set { _firmGUID = value; }
}

我得到了一个实用程序类来根据附加到数据实体类的属性进行验证。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
namespace Reform.Water.Business.Common
{
/// <summary>
/// Validation Utility
/// </summary>
public static class ValidationUtility
{
    /// <summary>
    /// Data entity validation
    /// </summary>
    /// <param name="data">Data entity object</param>
    /// <returns>return true if the object is valid, otherwise return false</returns>
    public static bool Validate(object data)
    {
        bool result = true;
        PropertyInfo[] properties = data.GetType().GetProperties();
        foreach (PropertyInfo p in properties)
        {
            //Length validatioin
            Attribute attribute = Attribute.GetCustomAttribute(p,typeof(ValidLengthAttribute), false);
            if (attribute != null)
            {
                ValidLengthAttribute validLengthAttribute = attribute as ValidLengthAttribute;
                if (validLengthAttribute != null)
                {
                    int maxLength = validLengthAttribute.MaxLength;
                    int minLength = validLengthAttribute.MinLength;
                    string stringValue = p.GetValue(data, null).ToString();
                    if (stringValue.Length < minLength || stringValue.Length > maxLength)
                    {
                        return false;
                    }
                }
            }
            //Range validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRangeAttribute), false);
            if (attribute != null)
            {
                ValidRangeAttribute validRangeAttribute = attribute as ValidRangeAttribute;
                if (validRangeAttribute != null)
                {
                    decimal maxValue = decimal.MaxValue;
                    decimal minValue = decimal.MinValue;
                    decimal.TryParse(validRangeAttribute.MaxValueString, out maxValue);
                    decimal.TryParse(validRangeAttribute.MinValueString, out minValue);
                    decimal decimalValue = 0;
                    decimal.TryParse(p.GetValue(data, null).ToString(), out decimalValue);
                    if (decimalValue < minValue || decimalValue > maxValue)
                    {
                        return false;
                    }
                }
            }
            //Regex validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRegExAttribute), false);
            if (attribute != null)
            {
                ValidRegExAttribute validRegExAttribute = attribute as ValidRegExAttribute;
                if (validRegExAttribute != null)
                {
                    string objectStringValue = p.GetValue(data, null).ToString();
                    string regExString = validRegExAttribute.RegExString;
                    Regex regEx = new Regex(regExString);
                    if (regEx.Match(objectStringValue) == null)
                    {
                        return false;
                    }
                }
            }
            //Required field validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRequiredAttribute), false);
            if (attribute != null)
            {
                ValidRequiredAttribute validRequiredAttribute = attribute as ValidRequiredAttribute;
                if (validRequiredAttribute != null)
                {
                    object requiredPropertyValue = p.GetValue(data, null);
                    if (requiredPropertyValue == null || string.IsNullOrEmpty(requiredPropertyValue.ToString()))
                    {
                        return false;
                    }
                }
            }
        }
        return result;
    }
}
}

[System.Security.Permissions.PermissionSetAttribute]允许对使用声明性安全性的代码应用PermissionSet的安全操作。

1
2
3
4
5
6
7
// usage:
public class FullConditionUITypeEditor : UITypeEditor
{
    // The immediate caller is required to have been granted the FullTrust permission.
    [PermissionSetAttribute(SecurityAction.LinkDemand, Name ="FullTrust")]
    public FullConditionUITypeEditor() { }
}

我总是使用属性,[Serializable][WebMethod][DefaultValue][Description("description here")]

但除此之外,C还有一个全局属性。

1
2
3
[assembly: System.CLSCompliant(true)]
[assembly: AssemblyCulture("")]
[assembly: AssemblyDescription("")]

1
2
3
4
5
// on configuration sections
[ConfigurationProperty]

// in asp.net
[NotifyParentProperty(true)]