2016-05-26 42 views
1

我目前正在爲Unity3D開發用戶界面編輯器。在這一點上,我有一個字典,其中一個鍵和值都代表一個類型。基於密鑰類型我想要的值類型的組件添加到遊戲物體並返回它:如果語句在Unity C#中爲false,但在手錶中爲true

protected Dictionary<string, string> eventHandlers = new Dictionary<string, string>(); 

public virtual EventHandler GetHandler(System.Type type) 
{ 
    string name = type.Name; 
    if(eventHandlers.ContainsKey(name)) 
    { 
     System.Type eventHandlerType = TypeUtility.GetType(eventHandlers[name], null); 
     return this.gameObject.AddComponent(eventHandlerType) as EventHandler; 
    } 
    return null; 
} 

問題在於我的if語句。顯然,eventHandlers.ContainsKey(name)返回false,因爲調用了返回null語句。但是,字典確實包含密鑰。即使更加狡猾:如果我在Visual Studio的手錶中輸入此聲明,這是真的。

  • 我開始用字典,但那也不行。
  • 我看着類型,它給了type.DeclaringMethod異常:System.InvalidOperationException:DeclaringMethod只能用於泛型參數。但是,我可以訪問名稱,正如您在上面的代碼中看到的。字符串名稱是正確的值,它不會在這裏打破。

有人知道爲什麼我的if語句是錯誤的,當它在手錶中是真的嗎?任何人都可以指引我走向正確的方向嗎?

[編輯] 的值是:

name "IOnClick" System.String 

eventHandlers 
    Count=1 
    System.Collections.Generic.Dictionary`2 
     [ 
      [System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089], 
      [System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089] 
     ] 
    ["IOnClick"] "OnClickHandler" System.Collections.DictionaryEntry 

type "InterfaceEditor.EventSlots.IOnClick" System.Type 
    DeclaringMethod System.InvalidOperationException: DeclaringMethod can only be used on generic arguments System.Reflection.MethodBase 
    Name "IOnClick" System.String 

[EDIT2] 所以,我想通了,在我的問題所在。

上面的代碼駐留在我的課InterfaceElement:

public abstract class InterfaceElement : MonoBehaviour, ISerializationCallbackReceiver 
{ 
    protected Dictionary<string, string> eventHandlers = new Dictionary<string, string>(); 
} 

對於我的不同InterfaceElements,像我的按鈕,我想我可以只覆蓋字典是這樣的:

public class Button : InterfaceElement, IOnClick 
{ 
    protected new Dictionary<string, string> eventHandlers = new Dictionary<string, string>() 
    { 
     { typeof(IOnClick).Name, typeof(OnClickHandler).Name } 
    }; 
} 

Appearantly,C#或者Unity不喜歡這個。什麼是正確的方式來做類似的事情?我不能使用構造函數,因爲我的InterfaceElement是MonoBehaviour,對吧?

+0

您應該添加到您的問題'name'的值和您的字典的所有鍵 –

+0

@ThomasAyoub我添加了值 –

+0

您可以嘗試'name.GetHashCode()== eventHandlers.ElementAt(0).Key。 GetHashCode()'? –

回答

1

所以。事實證明,新的不會做我認爲會的事。新不覆蓋字段,而是隱藏基本字段。這意味着基類仍然會看到基本字段。我的解決方法是不使用的字段,但在方法返回字典中,像這樣:

public abstract class InterfaceElement : MonoBehaviour 
{ 
    protected virtual Dictionary<System.Type, System.Type> GetEventHandlers() 
    { 
     return null; 
    } 

    public virtual EventHandler GetHandler(System.Type type) 
    { 
     Dictionary<System.Type, System.Type> eventHandlers = GetEventHandlers(); 
     if(eventHandlers != null && eventHandlers.ContainsKey(type)) 
      return this.gameObject.AddComponent(eventHandlers[type]) as EventHandler; 
     return null; 
    } 
} 

public class Button : InterfaceElement, IOnClick 
{ 
    protected override Dictionary<System.Type, System.Type> GetEventHandlers() 
    { 
     return new Dictionary<System.Type, System.Type>() 
     { 
      {typeof(IOnClick), typeof(OnClickHandler)} 
     }; 
    } 
} 

感謝您的評論,並幫助找到答案!

+0

您是否嘗試使用覆蓋而不是新建? –

+1

是的,你不能在字段上使用覆蓋。 –

+0

@ScubaKay每次調用函數時都不需要重新創建相同的字典,而是可以將字典存儲在專用字段中。假設你永遠不會更改字典,或者你主動想要更改共享。此外,如果您的代碼可能反覆運行,這只是值得的。 – Keen

相關問題