C# 轮询属性的最简单C代码?

C# 轮询属性的最简单C代码?,c#,properties,C#,Properties,我想知道轮询属性值的最简单代码,以便在其getter中执行该代码。 目前我正在使用:instance.property.ToString(),但我更喜欢没有可能的副作用或不必要的开销的东西。(我假设您试图避免仅仅将值赋给未使用的变量而得到的警告。) 您可以编写一个无操作扩展方法: public static void NoOp<T>(this T value) { // Do nothing. } GC.KeepAlive(instance.SomeProperty);

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

(我假设您试图避免仅仅将值赋给未使用的变量而得到的警告。)

您可以编写一个无操作扩展方法:

public static void NoOp<T>(this T value)
{
    // Do nothing.
}
GC.KeepAlive(instance.SomeProperty);
这根本不会阻塞值或触及它——只需调用getter即可。与
ToString
相比,该方法的另一个优点是,如果该值为空引用,则不会发生异常


每个值类型需要JIT编译一次方法,但这是一个相当小的成本…

在变量中捕获它是最好的方法-不会产生任何副作用,除非getter本身会产生副作用


var value=someObj.Property

我觉得这是个非常糟糕的主意。老实说,如果您在getter中有需要定期执行的逻辑,请将其从getter中取出并粘贴到方法中。我不喜欢跳入并维护这样的代码,一旦我最终弄明白它为什么要这样做,我就会重构它。

我会将getter中的代码提取到一个函数中,并从getter和轮询器调用该函数,如果这是您的选项。

我希望我理解正确。 首先

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);

我喜欢Jon Skeet的答案,但同样,这也可以在不必编写扩展方法的情况下工作:

public static void NoOp<T>(this T value)
{
    // Do nothing.
}
GC.KeepAlive(instance.SomeProperty);

KeepAlive
方法接受一个
对象
,与
NoOp
扩展方法类似,它不处理任何东西。

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

或者。。 (不确定全局变量是什么意思)但是如果它在一个对象中,那么您可以只获取全局对象上属性的getter来执行延迟加载,然后获取值

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

(但您可能无法访问那里的“实例”)

尽管这可能仍然是个坏主意,但我只想留下这个简洁的lambda解决方案:

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


Instance.Property肯定会执行getter的代码。请详细说明你的问题,我想我不明白。你说的“可能的副作用”是什么意思?如果你调用一个getter,那么执行get代码可能(取决于它的编写方式)导致副作用,不管你如何调用它。@Protector-你想实现什么?可能您要执行的代码不应该包含在属性getter中。@mcabral
Instance.Property
确实会轮询它,但这不是一个完整的语句。我不能在结尾加一个分号,希望编译器不会注意到。或者,您可以调用扩展方法
Touch
,如
instance.SomeProperty.Touch()那么至少你的代码给出了一些关于发生了什么的线索。这是真的,但至少它不是一个全局函数,它在其他方面没有用处。;)这的确是一段简单的代码,但对我来说,这简直是在浪费内存。这只是一个参考。它可以是一些基本类型,但无论如何都不会有太多内存。同时,你在做什么类型的编程,在变量中捕获某些东西会导致性能问题?这不会是一个问题(简单地使用
ToString
也不会),我只是好奇是否有更干净、更简单的方法来做。实际上,大多数代码只需要在类似于单例模式的场景中执行一次。@Protector:这是将单例执行的代码放入构造函数的一个很好的参数。它最多执行一次,但不必总是执行那一次。这就是为什么我不希望它出现在构造函数中。将它分配给一个未使用的变量不也会浪费内存吗?@Protector one:可能吧,但如果是局部变量(在大多数情况下,是特定于实现的),则只能使用堆栈内存。不,有一个重要的区别——它将框住任何值类型的值。我也不确定GC.KeepAlive(null)
做了什么。这段代码实际上与我的代码非常相似!那么,您将如何轮询您的
MyProp
属性以确保设置了
\u MyProp
?(这就是我要问的。)@protector-不,我建议将该代码放在全局级别,或者从实例的构造函数中设置全局变量。我认为让一个getter做一些事情而不仅仅是返回一个值是不好的做法。抱歉,但我不想让属性getter代码与对象的每个实例一起执行。你不必后悔,你可能是对的!但是我仍然有兴趣知道如何用我的方式来做。@Protector-您可以将成员定义设置为静态。这可能是一个比Jon Skeet的答案更好的解决方案,但他的答案更好。