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