簡體   English   中英

C#-在類或結構上重置struct的值

[英]C# - Reset the value of struct on class or struct

我正在嘗試使用Unity編寫一些腳本,但是我有一些問題需要了解struct的工作原理。

從代碼庫開始:

 public class Engine : MonoBehaviour {

   public Hero selectedHero;
   public List<Hero> heroes;

   public struct Hero {
     public string name;
     public Hero(string n) {
       name = n;
     }
   }
 } 

首先,我嘗試使一些功能選擇/取消選擇。

/* ... */
public Hero getSelected(Hero h) {
  return selectedHero;
}
public void setSelected(Hero h) {
  selectedHero = h;
}
public bool hasSelected(Hero h) {
  return (selectedHero != null);
}
public void clearSelected() {
  selectedHero = null; //  This is not working ! :'(
}
/* ... */

我得到了這個錯誤:

無法將null轉換為Hero因為它是值類型

我讀了很多有關C#和Unity腳本的知識,答案是:

構造不能為null,就像int不能為null,float不能為null一樣-它們都是值類型

但是呢 真正的解決方案是什么! 我使用了兩個難看的解決方案來避免這種情況:

解決方案#1我可以放置一個public bool hasSelected並始終在使用selected屬性之前對其進行測試。

解決方案#2是創建一個List<Hero> selected而不是簡單HeroList<Hero> selected ,如果Length為0或1,則進行處理。

是否存在更好的解決方案,更干凈?

額外的問題:如何創建一個基於測試的函數,該函數返回單個Hero,這是我最好的(丑陋的)解決方案:

public Hero GetHero(string name) {
    foreach (Hero hero in heroes) {
        if (hero.name == name) {
            return hero;
        }
    }
    return null; // Not working ?! What can I return ?!
 }

如果您需要類型可以為空,則聽起來應該將Hero為類(引用類型),而不是結構(值類型)。 您對代碼的更改將很小,只需交換關鍵字:

public class Hero {
    public string name;
    public Hero(string n) {
        name = n;
    }
}

如果有原因,您應該使用Struct而不是class,那么請使用default of檢查您的結構。

有時,當您期望一個結構並傳遞一個類時,程序的行為(或行為不當)可能會有所不同。

因此,這是您的兩種方法的更改:

       public bool hasSelected(Hero h)
        {
            return !(h.Equals(default(Hero)));
        }
        public void clearSelected()
        {
            selectedHero = default(Hero); 
        }

關於主要問題

值類型(int,struct等)不能以二進制表示形式表示null,這就是.NET不允許的原因。 但是.NET具有Nullable<T>結構,該結構為空表示添加了額外的字節。

關於選擇/取消選擇功能

我已經重構了您的代碼以使用struct:

public Hero GetSelected()
{
    return selectedHero;
}

public void SetSelected(Hero h)
{
    selectedHero = h;
}

public bool HasSelected()
{
    return !(selectedHero.Equals(default(Hero)));
}

public void ClearSelected()
{
    selectedHero = default(Hero);
}

關於獎金問題

很簡單,使用LinQ =)

public Hero GetHero(string name)
{
    return heroes.Where(w => w.name.Equals(name)).FirstOrDefault();
}

PS:“默認值”不是“空值”。

參考文獻:

希望對您有所幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM