[英]Using an interface as type parameter to generic method
我在Unity3d游戲工作使用C#,和我們有很多的情況下,我們需要訪問特定成員(比如, int health
一)的GameObject
。 我們使用以下代碼執行此操作:
GameObject obj;
if(obj.GetComponent<Player>() != null) {
obj.GetComponent<Player>().health--;
}
else if(obj.GetComponent<Robot>() != null) {
obj.GetComponent<Robot>().health--;
}
// more painful code
我想做的是讓所有這些類都實現IHealth
類的接口,然后執行obj.GetComponent<IHealth>().health--;
. 不過,這可能嗎? 我環顧四周,似乎不能將接口用作類型參數。
事實證明,這並不容易,而且可能不是一個好主意。 問題是GetComponent<T>
期望類型參數T
派生自Component
(當然,Unity 沒有記錄這一點)。 我需要讓Robot
、 Player
等都從一個抽象類派生,該抽象類本身繼承自Component
(通過MonoBehaviour
),並包含有關健康和其他領域的信息。 我懷疑這是否值得; 它可能會在其他地方導致同樣多的混亂代碼。
正如 SLaks 所指出的,接口作為泛型類型參數是完全可以接受的。 如果您的問題是通過接口訪問字段,那么我建議只需將您的字段更改為屬性。 如果由於某種原因您絕對必須保留該字段,只需提供一個隱式實現該接口的包裝屬性。 如果問題是字段和屬性具有完全相同的名稱(包括大小寫),則可以顯式實現該接口:
public interface IHealth { int Health { get; set; } }
// Change to a property
public class Ogre : IHealth { public int Health { get; set; } }
// Casing is different, so interface can be implemented implicitly
public class Player : IHealth {
int health;
public int Health { get { return health; } set { health = value; } }
}
// Name collision with Pascal casing, so implement explicitly
public class Robot : IHealth {
int Health;
int IHealth.Health { get { return Health; } set { Health = value; } }
}
// Later
GameObject obj;
var o = obj.GetComponent<IHealth>();
if (o != null) o.Health--;
我認為您有一個基本的設計問題,因為您的消費代碼需要了解每種類型。 如果您不考慮類型而采取相同的操作,那么只需使用好的 ol' 多態性:
public class Player: IHealth {}
public class Robot: IHealth {}
從 GetComponent 中刪除泛型參數並讓它返回一個 IHealth 對象,而不是一堆if
語句:
public IHealth GetComponent()
{
// return IHealth object here
}
在您的調用代碼中:
obj.GetComponent().DecreaseHealth();
為什么不只擁有一個組件Health
。 然后將它附加到你的游戲對象,在任何需要健康的腳本上有一個RequiresComponent
注釋,然后通過GetComponent<Health>();
獲取它GetComponent<Health>();
(將其緩存在私有變量中的相同對象腳本中)
如果您有多個始終在一起的“統計數據”,則可以使其更容易,例如
public class Status : MonoBehaviour
{
public float health;
public float armor;
}
我團結一致地發現,這是一個令人驚訝的常見“問題”。 不確定這是否是一個問題,因為這種想法確實可以幫助解決一些問題......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.