是否可以很容易地動態裝飾和?例如,可以說我有一個List<PointF>
。這個列表實際上是正弦函數的情節。我想通過這些要點併爲每個PointF添加一個標誌,判斷它是否爲高峯。動態裝飾c中的物體#
但我不想創建一個新的擴展的SpecialPointF或其他任何具有布爾屬性的東西。
判斷我所有你想要的懶惰,但懶惰的思想是如何真棒出生(也壞主意)
編輯:我會接受拳擊解決方案,以及任何有趣的黑客,你可以拿出。沒有什麼能夠阻止我獲得。我只想知道是否有更有趣的方式。
是否可以很容易地動態裝飾和?例如,可以說我有一個List<PointF>
。這個列表實際上是正弦函數的情節。我想通過這些要點併爲每個PointF添加一個標誌,判斷它是否爲高峯。動態裝飾c中的物體#
但我不想創建一個新的擴展的SpecialPointF或其他任何具有布爾屬性的東西。
判斷我所有你想要的懶惰,但懶惰的思想是如何真棒出生(也壞主意)
編輯:我會接受拳擊解決方案,以及任何有趣的黑客,你可以拿出。沒有什麼能夠阻止我獲得。我只想知道是否有更有趣的方式。
如果有一種方法可以計算每點的數據,則不需要向其添加標誌,您可以使用extension方法,而無需對其進行擴展。
Something like PointF.isPeak();
它的工作原理是這樣的:
public static class Extensions
{
public static bool isPeak (this PointF p)
{
do crazy math...
return result;
}
}
,瞧,你有你的PointF類的計算。
順便說一句,公共靜態類必須在最外層的範圍內,不能嵌套。
+1。非常好的建議,儘管'isPeak'沒有與.NET命名約定一致(第一個字符應該大寫) – 2010-04-29 17:11:53
這是一個很棒的想法。我喜歡它。 – 2010-04-29 17:17:12
@Francisco:擴展方法是一個好主意,但是在這種情況下,一個點將如何知道它不在其中的高峯?除非點包含指向該系列的指針,否則它是... – 2010-04-29 17:18:39
不,沒有辦法做(具體)你要求什麼。
假設您使用的是C#3.0+,您可以使用匿名類型來執行此操作,前提是您不希望在函數之外公開信息。
var decoratedList = sourceList.Select(pt => new
{
IsPeak = GetIsPeak(pt),
Point = pt
}).ToList();
這會給你一個新的List<T>
對象。這可能不能解決您的問題,因爲您無法將此功能擴展到單個功能調用之外,並且您正在創建一個新列表,而不是修改現有列表,但希望這會有所幫助。
這是一個很酷的想法。我還沒有使用匿名類型,所以我甚至沒有考慮過。 我們使用最新的c#非常酷,所以它不是問題。 – 2010-04-29 17:07:46
@Oren:他們很好,但最大的缺陷是無法將他們暴露在你的功能之外。如果你需要這樣做,你必須創建一個類似簽名的自己的簡單包裝類,然後只說'新的WrapperClass {...'而不是'new {...' – 2010-04-29 17:09:35
不,這是不可能的。
最近將剛剛創建
var decorationData = new Dictionary <Object, bool>
,然後在那裏保存的值。不需要直接擴展類型。您甚至可以使用擴展方法來訪問存儲的數據,然後該數據看起來像是對象的直接屬性。
public static class PointFPeakExtensions
{
private static var decorationData = new Dictionary <PointF, bool>
public static bool IsPeak (this PointF point)
{
return decorationData[point];
}
public static void SetPeak (this PointF point, bool isPeak)
{
decorationData[point] = isPeak;
}
}
並添加到您的編輯:
你也可以使用包含剛裝修的數據和引用類型(同樣爲可空類型在類庫實現了一個通用型解決這個)。然而,這仍然意味着你必須改變你使用類型的地方的簽名(這可能不是你在尋找裝飾器時想做的事情)。
它可能有可能做到這一點使用新的dynamic關鍵字和ExpandoObject
建立在C#4.0,但我沒有與它的第一手經驗呢。據我瞭解,是爲了輕鬆解決這個確切的問題,因此可以說
dynamic something = new ExpandoObject();
something.Anything = "whatever you want";
我相信有可能擴展動態現有的類型,但它可能需要創建一個新的子類,它會破壞練習的全部目的。
可以使用擴展方法創建幾乎相同的解決方案。 ExpandoObject
在內部實現爲Dictionary
,但它添加了優雅的本地語法。
class Program {
static void Main(string[] args)
{
PointF p = new PointF(0, 0);
p.SetFlag(true);
if (p.GetFlag())
Console.WriteLine("win");
}
}
public static class Extensions
{
private static Dictionary<PointF, bool> flags = new Dictionary<PointF, bool>();
public static bool GetFlag(this PointF key)
{
return flags[key];
//OR return flags.ContainsKey(key) ? flags[key] : false;
}
public static void SetFlag(this PointF key, bool val)
{
flags[key] = val;
}
}
而不是p.SetFlag你的意思是調用Extensions.SetFlag(p,true); ? – 2010-04-29 17:18:27
不,擴展方法允許你打電話看起來像這樣「原生」。它會自動爲您調用'Extensions.SetFlag(p,true)'。 – 2010-04-29 17:21:17
我剛剛給你+1的結束句。但是,不太確定你的問題的答案。 – 2010-04-29 16:56:34