为什么这个有效?

4

我在谷歌上搜索,试图找到一种调用Control.DataBindings.Add的方法,而不使用字符串字面值,而是从属性本身获取属性名称,我认为这样会更少出错,至少对于我的特定情况是这样的,因为当我重命名一个属性时,我通常让Visual Studio来完成。所以我的代码应该是这样的:DataBindings.Add(GetName(myInstance.myObject)...而不是DataBindings.Add("myObject"...。所以我找到了这个:

    static string GetName<T>(T item) where T : class
    {
        var properties = typeof(T).GetProperties();
        if (properties.Length != 1) throw new Exception("Length must be 1");
        return properties[0].Name;
    }

假设我有一个名为One的属性,那么可以这样调用:string name = GetName(new { this.One });,这将返回"One"。我不知道它为什么能运行,是否安全。我甚至不知道new { this.One }是什么意思。而且我也不知道在哪种情况下properties.Length不为1。
顺便说一下,我刚测试了一下把One属性重命名为Two,Visual Studio就把new { this.One }变成了new { One = this.Two },当与GetName函数一起使用时,它给我返回了"One",这使得整个过程变得没有意义,因为无论如何我都会传递给Control.DataBindings.Add一个名为"One"的属性名称。

我简直不敢相信VS会发出new { this.One },除非你一开始就使用了匿名类。 - leppie
请参考以下链接:https://dev59.com/S3M_5IYBdhLWcg3wjj4p - Ian Ringrose
2个回答

6

new { this.One }创建了一个实例,这个实例是一个匿名类型,只有一个属性,因为你没有指定名称,所以它被称为"One"。这就是为什么它能够工作的原因。

如果你使用new { One = this.Two },你给属性命名为"One"。如果你省略掉"One ="这部分,它会再次有效。

然而,如果不知道它的用途或者不使用匿名类型调用它,那么你使用的方法可能会被误解。

如果你不想使用字符串字面量,还有另一种方法,在网上可以找到一些示例:
http://www.codeproject.com/Tips/57234/Getting-Property-Name-using-LINQ.aspx


我想我只能坚持使用字符串字面值 :( - Juan
你不必这样做。看看我的编辑,可能会有更简洁的方法。 - Botz3000
ASP.NET MVC广泛使用匿名类型来指定诸如HTML属性之类的内容。 - Bryan Watts

3

不,您不必坚持使用字符串文字:

public static class ControlBindingsCollectionExtensions
{
   public static void Add<T>(this ControlBindingsCollection instance, Expression<Func<T, object>> property)
    {
        var body = property.Body as UnaryExpression;
        var member = body.Operand as MemberExpression;
        var name = member.Member.Name;
        instance.Add(name);
    }
}

使用方法:

Control.DataBindings.Add<MyClass>(m => m.MyProperty);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接