考虑以下片段:
[DebuggerStepThrough]
private A GetA(string b)
{
return this.aCollection.FirstOrDefault(a => a.b == b);
}
如果我使用F11,调试器不会跳过该功能,而是停在 a.b == b 。
有没有办法跳过这个功能而不是使用F10?
答案 0 :(得分:4)
IMO这是C#编译器中的一个错误。编译器还应将这些属性放在匿名方法上。解决方法是回退到C#编译器为您完成的手动工作:
[DebuggerStepThrough]
private A GetA(string b)
{
var helper = new Helper { B = b };
return this.aCollection.FirstOrDefault(helper.AreBsEqual);
}
private class Helper
{
public string B;
[DebuggerStepThrough]
public bool AreBsEqual(A a) { return a.b == this.B; }
}
但当然这是令人讨厌的,而且非常难以理解。这就是C#编译器应该这样做的原因。但是C#团队的难题当然是:你在方法中放置哪些属性必须复制到内部匿名方法,哪些不应该?
答案 1 :(得分:2)
我可以看到它为什么会发生,但没有办法解决它。也许有人可以建立在此基础之上lambda表达式被编译成匿名方法。
我明白了:Program.GetA.AnonymousMethod__0(测试a)
就像你在你所显示的方法中调用另一个方法一样,按F11将进入该方法。例如/
[DebuggerStepThrough]
static A GetA<A>(IList<A> aCollection, string b) where A : Test
{
DoNoOp();
return aCollection.FirstOrDefault(a => a.b == b);
}
static void DoNoOp()
{
// noop
Console.WriteLine("got here");
}
答案 2 :(得分:0)
这困扰了我很长一段时间,今天我想出了一种在.NET 4.0中使用表达式树来实现它的方法。
请考虑以下代码:
private class Borked
{
public object X
{
[DebuggerStepThrough]
get { throw new NotImplementedException(); }
}
}
private void SomeMethod()
{
var bad = new Borked();
object obj = bad.TryGet(o => o.X);
}
现在 - 我可以调用此代码而不会错过任何一个节拍 - 调试器试图停止的唯一地方是Borked的破坏的getter属性 - 这就是我在那里添加DebuggerStepThrough
属性的原因。
我没有接受一个lambda,而是接受一个表达式树(使用相同的语法!!),然后在运行时编译并运行它 - 这是 little 更多的工作(几乎没有) )而不是使用普通的lambda,它不适用于所有东西,但对于简单的Linq查询等,它的效果很好。
所有的魔法都发生在以下方法中 - 同样,最初用于接受常规Func<>
参数 - 但是在抛出异常时暂停调试器(尽管有逐步属性),所以我现在用Expression<Func<>>
这样做:
[DebuggerStepThrough]
public static T TryGet<OT, T>(this OT obj, params Expression<Func<OT, T>>[] getters)
{
T ret = default(T);
if (getters != null)
{
foreach (var getter in getters)
{
try
{
if (getter != null)
{
var getter2 = (Func<OT, T>)getter.Compile();
ret = getter2(obj);
break;
}
}
catch
{ /* try next getter or return default */ }
}
}
return ret;
}
这是对的 - 你只需调用.Compile()
并将返回值转换为可以立即调用的常规Func<>
! - 这有多容易?!
在我的实现中,我让用户传入多个参数,以便他们有办法获得回退值(并且只需要创建/评估该回退值 IF )。
另外,我不确定Debug事件被抑制的原因是因为VisualStudio的“Just my Code”,还是因为它在这种方法中以内联方式运行......但是无论哪种方式它都有效,唱吧!!
现在,我猜测在运行时在表达式上调用.Compile
方法并不是超快,但实际上,它似乎并没有给我增加任何性能损失。我的疑问。所以,我很兴奋(请原谅多重/多余的刘海和interobang等等。)
答案 3 :(得分:-3)
我不确定这是否有效,但您可以尝试将该属性放在lambda表达式
上[DebuggerStepThrough]
private A GetA(string b)
{
return this.aCollection.FirstOrDefault([DebuggerStepThrough]a => a.b == b);
}