2011-12-20 50 views
0

在一個較大的WP7項目的工作,我一直過這個問題來了:設置在C#中運行時類的屬性導致Visual Studio崩潰

任何時候,我在我的代碼設置一個屬性,它崩潰的Visual Studio 2010。 所以我決定做一個適當的測試來嘗試隔離問題。 以下代碼是一個簡短的wp7應用程序示例,它具有相同的問題。每當代碼嘗試設置name屬性時,它都會使Visual Studio崩潰。

注:我沒有安裝的加載項,當我嘗試在安全模式下運行,我得到了錯誤

任何幫助,將不勝感激

「項目類型不受此安裝支持」
using System; 
using System.Collections.Generic; 
using System.Windows; 
using Microsoft.Phone.Controls; 

namespace propertytest 
{ 
    public partial class MainPage : PhoneApplicationPage 
    { 
     public string name 
     { 
      get { return name; } 
      set 
      { 
       //crash! 
       if (value != name) 
       { 
        name = value; 
        hi(name); 
       } 
      } 
     } 
     void hi(string name) 
     { 
      MessageBox.Show("hi "+name); 
     } 
     // Constructor 
     public MainPage() 
     { 
      InitializeComponent(); 

      // Set the data context of the listbox control to the sample data 
      DataContext = App.ViewModel; 
      this.Loaded += new RoutedEventHandler(MainPage_Loaded); 
      name = "your name"; 
     } 

     // Load data for the ViewModel Items 
     private void MainPage_Loaded(object sender, RoutedEventArgs e) 
     { 
      if (!App.ViewModel.IsDataLoaded) 
      { 
       App.ViewModel.LoadData(); 
      } 
     } 
    } 
} 

調用堆棧:

propertytest.dll!propertytest.MainPage.name.set(string value) Line 14 C# 
propertytest.dll!propertytest.MainPage.MainPage() Line 34 + 0xb bytes C# 
    mscorlib.dll!System.Reflection.RuntimeConstructorInfo.InternalInvoke(System.Reflection.RuntimeConstructorInfo rtci, System.Reflection.BindingFlags invokeAttr,  System.Reflection.Binder binder, object parameters, System.Globalization.CultureInfo culture, bool isBinderDefault, System.Reflection.Assembly caller, bool verifyAccess, ref  System.Threading.StackCrawlMark stackMark)  
mscorlib.dll!System.Reflection.RuntimeConstructorInfo.InternalInvoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture, ref System.Threading.StackCrawlMark stackMark) + 0x114 bytes  
mscorlib.dll!System.Activator.InternalCreateInstance(System.Type type, bool nonPublic, ref System.Threading.StackCrawlMark stackMark) + 0xf0 bytes 
mscorlib.dll!System.Activator.CreateInstance(System.Type type) + 0x2 bytes 
Microsoft.Phone.dll!System.Windows.Navigation.PageResourceContentLoader.BeginLoad_OnUIThread(System.AsyncCallback userCallback, System.Windows.Navigation.PageResourceContentLoader.PageResourceContentLoaderAsyncResult result) + 0xe6 bytes 
Microsoft.Phone.dll!System.Windows.Navigation.PageResourceContentLoader.BeginLoad.AnonymousMethod__0(object args) + 0x11 bytes 
mscorlib.dll!System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo rtmi, object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object parameters, System.Globalization.CultureInfo culture, bool isBinderDefault, System.Reflection.Assembly caller, bool verifyAccess, ref System.Threading.StackCrawlMark stackMark) 
mscorlib.dll!System.Reflection.RuntimeMethodInfo.InternalInvoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture, ref System.Threading.StackCrawlMark stackMark) + 0x168 bytes 
mscorlib.dll!System.Reflection.MethodBase.Invoke(object obj, object[] parameters) + 0xa bytes 
mscorlib.dll!System.Delegate.DynamicInvokeOne(object[] args) + 0x98 bytes 
mscorlib.dll!System.MulticastDelegate.DynamicInvokeImpl(object[] args) + 0x8 bytes 
mscorlib.dll!System.Delegate.DynamicInvoke(object[] args) + 0x2 bytes 
System.Windows.dll!System.Windows.Threading.DispatcherOperation.Invoke() + 0xc bytes  
System.Windows.dll!System.Windows.Threading.Dispatcher.Dispatch(System.Windows.Threading.DispatcherPriority priority) + 0x83 bytes 
System.Windows.dll!System.Windows.Threading.Dispatcher.OnInvoke(object context) + 0x8 bytes 
System.Windows.dll!System.Windows.Hosting.CallbackCookie.Invoke(object[] args) + 0x19 bytes 
System.Windows.dll!System.Windows.Hosting.DelegateWrapper.InternalInvoke(object[] args) + 0x2 bytes 
System.Windows.RuntimeHost.dll!System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(System.IntPtr pHandle, int nParamCount, System.Windows.Hosting.NativeMethods.ScriptParam[] pParams, ref System.Windows.Hosting.NativeMethods.ScriptParam pResult) + 0x5e bytes 
[External Code] 



**Debug Output:** 
'UI Task' (Managed): Loaded 'mscorlib.dll' 
'UI Task' (Managed): Loaded 'System.Windows.RuntimeHost.dll' 
'UI Task' (Managed): Loaded 'System.dll' 
'UI Task' (Managed): Loaded 'System.Windows.dll' 
'UI Task' (Managed): Loaded 'System.Net.dll' 
'UI Task' (Managed): Loaded 'System.Core.dll' 
'UI Task' (Managed): Loaded 'System.Xml.dll' 
'UI Task' (Managed): Loaded '\Applications\Install\1782A5A4-3D00-47D3-A109-B889805E61F9\Install\propertytest.dll', Symbols loaded. 
'UI Task' (Managed): Loaded 'Microsoft.Phone.dll' 
'UI Task' (Managed): Loaded 'Microsoft.Phone.Interop.dll' 
'UI Task' (Managed): Loaded '\Applications\Install\1782A5A4-3D00-47D3-A109-B889805E61F9\Install\Microsoft.Phone.Controls.dll' 
+1

+1純粹用於發佈堆棧溢出時堆棧溢出的問題。 – 2011-12-20 20:00:47

回答

2

你有一個無限遞歸循環

該位

if (value != name)調用屬性

例如的消氣這位

get { return name; }這反過來調用自己,直到你吹堆棧。

您需要使用後臺字段將值存儲在後臺字段中;

private string _name 

public string name 
     { 
      get { return _name; } 
      set 
      { 
       // won't crash any more 
       if (value != _name) 
       { 
        _name = value; 
        hi(name); 
       } 
      } 
     } 
5

你遞歸調用的二傳手:

 set 
     { 
      if (value != name) 
      { 
       name = value; // <-- Argh! Recursion! 
       hi(name); 
      } 
     } 

如果你想實現的getter/setter這種方式,你需要使用一個私有成員變量:

 private string _name; 
     public string name 
     { 
      get { return _name; } 
      set 
      { 
       if (value != _name) 
       { 
        _name = value; 
        hi(_name); 
       } 
      } 
     } 
+0

識別這些情況的一種方法是堅持MS命名約定。在這種情況下,該屬性將被稱爲Name,可能會更明顯。 – 2011-12-20 19:48:34

+1

我認爲他先遞歸地調用getter,好像check會遞歸地調用getter,它永遠不會到達你指定的那一行,這確實也會導致一個遞歸循環。 – 2011-12-20 19:52:47

+0

順便說一句,我會建議使用String.Compare()進行字符串比較。 – invalidusername 2011-12-20 22:47:58