获取属性的最简单C#代码是什么?

4
我想知道最简单的代码来轮询属性值,以执行其getter中的代码。
目前我正在使用:instance.property.ToString();,但我更希望有一些没有可能引起副作用或不必要开销的东西。

2
Instance.Property一定会执行getter的代码。请详细说明您的问题,我不认为我理解它。 - mcabral
2
你是什么意思说“可能的副作用”?如果你调用一个getter,get代码就会被执行,不管你怎么调用它,都可能(取决于代码编写方式)导致副作用。 - jlew
1
@Protector - 你想要实现什么?也许你想要执行的代码不应该在属性的getter中。 - tkerwood
@mcabral Instance.Property 确实会轮询它,但这并不是一个完整的语句。我不能只在末尾加上一个分号,希望编译器不会注意到。 - Protector one
1
或者,你可以将你的扩展方法命名为 Touch,例如 instance.SomeProperty.Touch(); 这样至少你的代码能够给出一些关于正在发生什么的线索。 - Robert Harvey
显示剩余9条评论
8个回答

16
我猜你是想避免直接将值赋给一个未使用的变量所导致的警告。
你可以编写一个空操作的扩展方法:
public static void NoOp<T>(this T value)
{
    // Do nothing.
}

然后调用:

instance.SomeProperty.NoOp();

这不会包装值或者直接接触它 - 只会调用getter。相比于使用ToString的另一个优点是,如果值为null引用,则不会出现错误。

但是它每个值类型需要一次JIT编译,但这是一个相当小的代价...


将其分配给未使用的变量也会浪费内存,不是吗?(而且我确实不想看到那个警告。) - Protector one
@Protector one:可能是的,但只有在它是局部变量时才使用堆栈内存(在大多数情况下;具体实现可能会有所不同)。 - Jon Skeet

5

我认为这听起来是一个非常糟糕的想法。如果你的getter中有需要经常执行的逻辑,请将其从getter中移出并放入方法中。我不希望跳进去维护那样的代码,一旦我最终弄清楚它为什么会做某些事情,我就会对其进行重构。


实际上,大部分代码只需要执行一次——这就像单例模式的场景。 - Protector one
@Protector:这是将单独执行的代码放置在构造函数中的一个好理由。 - Robert Harvey
它最多只会执行一次,但不一定总是要执行那一次。这就是为什么我不想把它放在构造函数中。 - Protector one

3
我建议你将getter中的代码提取到一个函数中,并在getter和轮询器中都调用该函数,如果这对你来说是可行的话。

1
这可能是比Jon Skeet的答案更好的解决方案,但他的回答更好地回答了问题。 - Protector one

0

虽然这可能仍然不是一个好主意,但我只想提供这个简洁的lambda解决方案:

((Func< [TYPE_OF_PROPERTY] >)(() => instance.Property))();

0

我希望我理解得正确。 首先

class MyClass
{
   public int Number{get;set;}
}

var cl = new MyClass();
cl.Number.ToString();

ToString() 方法并不一定返回值。对于基元类型,是的,但对于其他更复杂的类,通常只返回完全限定名称。我猜这不是你想要的。

要执行 getter,需要使用一些反射。

var propInfo = this.GetType().GetProperty("Number");
int val = (int)propInfo.GetValue(cl, null);

0

我喜欢Jon Skeet的答案,但是在同样的思路下,不必编写扩展方法也可以实现:

GC.KeepAlive(instance.SomeProperty);

KeepAlive 方法接受一个 object,并不对其进行任何操作,类似于 NoOp 扩展方法。


2
不,这里有一个重要的区别 - 它将装箱任何值类型的值。我也不确定 GC.KeepAlive(null) 是做什么的。 - Jon Skeet

0

我认为你需要将代码移动到其他地方。因此,请尝试在“实例”对象的构造函数中设置全局变量。

或者,(不确定您所说的全局变量是什么),但如果它在一个对象中,则可以使用全局对象上的getter来进行惰性加载并获取值。

string _myProp;
public string MyProp
{ 
   get
   {
     if (String.IsNullOrWhiteSpace(_myProp))
     {
        _myProp =  GetTheValueFromWhereEver();
     }
     return _myProp;
   }
}

(但您可能没有访问那里的“实例”)


这段代码实际上与我的代码非常相似!那么,你如何轮询你的 MyProp 属性以确保 _myProp 已设置?(这就是我要问的。) - Protector one
@protector - 不是的,我建议将该代码放置在全局级别或从实例的构造函数中设置全局变量。我认为,拥有一个除了返回值之外的其他操作的getter方法是不好的做法。抱歉。 - tkerwood
但我不想让属性 getter 代码在 每个 对象实例中都执行。而且你不必道歉 - 你可能是对的!但我仍然对如何按我的方式操作感兴趣。 - Protector one
@Protector - 你可以将成员定义为静态的。 - tkerwood

0

将其存储在变量中是最好的方法 - 除非getter本身引起副作用,否则不会产生任何副作用。

var value = someObj.Property;


没错,但至少它不是一个没有用处的全局函数。;) - WolfgangSenff
这确实是简单的代码,但对我来说感觉像是浪费内存。 - Protector one
这只是一个引用。它可以是一些原始类型,但无论如何都不会占用太多内存。同时,你正在进行什么类型的编程,将某些内容捕获到变量中会导致性能问题? - WolfgangSenff
这不是问题(仅使用 ToString 也不是问题),我只是很好奇是否有更简洁、更简单的方法来做到这一点。 - Protector one

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