簡體   English   中英

使用接口作為泛型方法的類型參數

[英]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 沒有記錄這一點)。 我需要讓RobotPlayer等都從一個抽象類派生,該抽象類本身繼承自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.

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