Невозможно увидеть переменные уровня класса при отладке в Visual Studio 2013

Я наблюдаю некоторое нечетное поведение при отладке некоторого кода С# в VS 2013. Когда я наводил курсор на любые переменные, привязанные к текущему методу, я могу видеть информацию о переменных. На скриншоте ниже вы можете увидеть, что ivSimulation закреплена и отображается информация. Однако, хотя вы не можете сказать, у меня была указатель мыши на this._simulator, и ничего не появилось. QuickWatch тоже ничего не показывает.

enter image description here

У другой коллеги также есть такая же проблема. Мы попробовали очистить наши папки и получить последнюю информацию. И мы также попытались изменить настройку в VS (Tools → Options → Debugging → General → Use Managed Compatibility Mode) для проверки, но это тоже не сработало. Видимо, это сработало для других. Это было прекрасно в VS 2012 года.

Любые идеи? Как я могу получить переменные уровня класса для показа в отладчике?

Изменить: Еще одна часть головоломки

Если я нахожусь над this, я вижу, что это прозрачный прокси. Не уверен, почему это произойдет.

enter image description here

Другая часть:

this относится к классу, который происходит от ContextBoundObject. Мы делаем это, чтобы мы могли использовать перехват для ведения журнала и обработки исключений. Возможно, именно по этой причине.

И я был неправ; это не работает в VS2012. Возможно, я никогда не замечал этого раньше.

Если я попытаюсь отобразить значение в непосредственном окне, это то, что я получаю:

? this._coater.Equipment.Line.Unit.Plant.Site.SiteId Не удается получить полей или методов вызова в экземпляре типа 'Company.Mes.Core.Components.Logic.ModuleDerating.StandardDeratingComponentLogic' потому что это прокси для удаленного объекта.

Ответ 1

Это потому, что this является прозрачным прокси.

Следующие скриншоты демонстрируют эту проблему, учитывая пример кода внизу.

Сначала создадим реальный объект и наведите указатель на это свойство Name:

enter image description here

Теперь создайте прокси для объекта. enter image description here

Обратите внимание, что я наводил курсор на экземпляр, чтобы показать, что он прозрачный прокси.

Теперь наведите указатель мыши на свойство Name прозрачного экземпляра прокси. enter image description here

Ничего не видно! Прозрачный прокси делает умное марширование вызовов к базовому объекту, но IDE явно не может понять это, поскольку возвращаемый прокси-объект является динамически сгенерированным классом на основе класса Foo.

И результат для полноты.

enter image description here

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Text;

namespace ConsoleApplication27
{
    class Program
    {
        static void Main(string[] args)
        {
            Foo foo = new Foo(){ Name = "My Foo1" };

            Console.WriteLine(foo.Name);

            FooProxy fooProxy = new FooProxy(foo);

            Foo proxiedFoo = (Foo)fooProxy.GetTransparentProxy();

            Console.WriteLine(proxiedFoo.Name);
        }
    }

    public class Foo : MarshalByRefObject
    {
        public string Name { get; set; }
    }

    public class FooProxy 
        : RealProxy
    {
        private Foo _target;

        public FooProxy(Foo target) : base(typeof(Foo))
        {
            this._target = target;
        }

        public override IMessage Invoke(IMessage msg)
        {
            return InvokeRemoteCall((IMethodCallMessage)msg, this._target);
        }

        /// <summary>
        /// Invokes the remote call.
        /// </summary>
        /// <param name="methodCall">The method call.</param>
        /// <param name="target">The target.</param>
        /// <returns>A <see cref="ReturnMessage"/></returns>
        private static IMessage InvokeRemoteCall(IMethodCallMessage methodCall, object target)
        {
            MethodInfo method = methodCall.MethodBase as MethodInfo;

            object callResult = (target != null) ? method.Invoke(target, methodCall.InArgs) : null;

            LogicalCallContext context = methodCall.LogicalCallContext;

            var query = method.GetParameters().Where(param => ((ParameterInfo)param).IsOut);

            ParameterInfo[] outParameters = query.ToArray();

            return new ReturnMessage(callResult, outParameters, outParameters.Count(), context, methodCall);
        } 
    }
}

Ответ 2

Может быть, что * this._simulator * назначается, но не используется нигде (пока), поэтому отладчик оптимизирует это и не отображает эти переменные.

Если это так, просто попробуйте, например, после того, как назначение использует метод ToString(), а затем поместите точку останова после него.

...
this._simulator = GetEquipment(ivSimulation);
this._simulator.ToString();
//Another line with the break point here