[英]The dream to inherit from a struct in c#
在那里,我在C#XNA 4.0中制作2D游戲,並再次遇到我的小煩惱; 矩形 。 對於那些使用基本碰撞的人來說,這幾乎是必需的。 對於幾乎所有創建的游戲對象,您都需要有一個矩形。 然后我去改變X,檢查碰撞或其他任何東西。 在那里,我開始了objectName.Rectangle.Whatever
的永無止境的戰斗。 為了解決這個問題,我當然會給出一些objectName屬性/方法來為我訪問這些屬性/方法。
然后我敢於夢想。 我有一個偉大的設計來制作一個基本的游戲對象類,所有drawable將繼承,這將允許父母,精確的本地坐標(浮點數),並保持紋理/ spritebatch。 為了完成這個,我准備從Rectangle繼承,使用它擁有的所有方法和屬性。 哎呀,每當需要一個Rectangle的東西時,我可能會懶得說objectName,而不是objectName.Rectangle。
然后我意識到,不是機會。 我開始感到沮喪,因為我很聰明的想法被砸碎了。 從那以后,我完美的小班級擁有一個矩形,各種方法和屬性根據需要訪問它。 我也有機會從XNA DrawableGameComponent繼承它。 雖然從長遠來看這更實用,每次我查看繪制或更新方法並看到我經常想到的矩形調用時,是否有希望做我想要的事情? 我可以做一些聰明的工作嗎? 或者是從一個真正被我掌握的矩形繼承而來?
雖然使用XNA中提供的DrawableGameComponent類允許大多數與游戲對象相關的動作發生在類Update()方法中,但每次在類之外我需要引用的不是Rectangle的屬性,而是Rectangle本身,我稍微考慮到實際上我的對象實際上是各種各樣的方式,並且加強了Rectangle。 然后我再一次發現自己在問:
有沒有辦法從預定義的結構繼承,或者給項目留下你的印象(一種解決方法)?
繼承否,但您可以使用擴展方法向Rectangle對象添加許多“默認”功能。 例如
//(inside a static class)
public static int GetSurface(this Rectangle rect){return rect.Width * rect.Height;}
//calling
Rectangle rect;
var s = rect.GetSurface();
也就是說,我通常做的是封裝所述結構。 使用該類作為基礎對象,並添加一個運算符,以便可以將其隱式轉換為Rectangle。 這樣它就可以傳遞給一個需要一個矩形而不需要強制轉換的方法。
public class MyRect //class so you can inherit from it, but you could make your own struct as well
{
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public int Right { get { return X + Width; } }
public int Bottom{ get { return Y + Height; } }
public static implicit operator Rectangle(MyRect rect)
{
return new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
}
public static implicit operator MyRect(Rectangle rect)
{
return new MyRect { X = rect.X, Y = rect.Y, Width = rect.Width, Height = rect.Height };
}
}
}
現在,您可以手動或從現有的rect創建自己的rect:
MyRect rect = ARectangleVar
並且您可以在遺留方法中使用它,這些方法期望不轉換矩形
這是一個可能的解決方法(把它放在MyClass
,你所說的具有Rectangle屬性的類):
public static implicit operator Rectangle(MyClass obj)
{
return obj.Rectangle;
}
這將允許您將對象傳遞給期望Rectangle
的方法,並且它可以工作。 請注意,與真正的繼承不同,存在的Rectangle與傳入的MyClass
實例不同,它只是由值構成的結構。
值類型從根本上與適用於類類型的繼承風格不兼容,但是能夠以這樣的方式聲明“派生結構”將有助於編譯器識別派生之間的雙向身份保留轉換。類型和原始。 派生的結構將需要只有一個字段,稱為“Base”(盡管C#編譯器可以接受關鍵字base
作為替代),其類型是派生的結構的類型。 名稱與周圍類型的名稱不匹配的“Base”的所有成員將被視為封閉結構的成員。
“派生結構”提供的主要內容,但目前缺乏的主要內容是:
我不確定是否需要對運行時進行任何更改以支持任何這些功能,如果接受盒裝派生類型的項目只能將其取消裝箱為同一派生類型; 允許將框架版本的結構直接轉換為身份可轉換派生的實例,這將有所幫助,但可能會增加復雜性。 我不確定是否需要這樣的行為來使泛型工作。 不幸的是,我覺得許多負責做出這種決定的人真的不喜歡價值類型。 由於.net歷史早期的一些設計決策(特別是缺乏“const ref”參數和通過ref
公開屬性的方法),使結構以語義正確的方式工作可能是一個挑戰,我想一些實現者寧願使用結構的問題作為改進.net處理它們的借口,而不是添加可以解決問題的功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.