我正在做一個練習,我在理解如何開始時遇到了一些麻煩。練習是這樣的:
給定介面
public interface I<T> { T P {get;} }
撰寫擴展方法“Indexing”,給定一個型別為“I< T >”的元素陣列“s”,其中“T”是一個只能用列舉型別實體化的引數,它會生成一個關聯每個值的字典“ “T”型別的 v”,在呼叫方法時具有“s”元素的子序列“s”,其具有“v”作為“P”屬性的值。
例如,通過使用 *enum Day { Mo, Tu, We, Th, Fr } *,如果“arr”是陣列[e0, e1, e2, e3, e4, e5],其中:
e0 - ... P == Day.Mo ...
e1 - ... P == Day.Mo ...
e2 - ... P == Day.We ...
e3 - ... P == Day.Mo ...
e4 - ... P == Day.Fr ...
e5 - ... P == Day.We ...
你會得到:
var res = arr.Indexing ();
for (int i = 1; i < arr.Length; i) arr[i] = arr [0];
// even changing arr is still true that
// res[Day.Mo] == [e0 , e1 , e3]
// res[Day.Tu] empty array
// res[Day.We] = [e2 , e5]
// res[Day.Th] empty array
// res[Day.Fr] = [e4]
我不想要一個完全解決的練習,但我需要一個提示才能開始作業。我想我錯過了關于 I< T > 的實施的一些東西(這是我第一次看到這樣的東西)。特別是,我對如何創建擴展方法以及如何測驗給定的示例有疑問。
提前致謝。
uj5u.com熱心網友回復:
擴展方法
擴展方法只是呼叫靜態方法的一種便捷方式,它主要對特定型別進行操作。例如,下面的方法 Print 可以用兩種方式撰寫。
public static void Print(string str)
{
Console.WriteLine(str);
}
public static void Print(this string str)
{
Console.WriteLine(str);
}
如您所料,第一個被呼叫。Print("Hello World!");
第二個(擴展方法)可以直接在字串上呼叫。"Hello World!".Print();
擴展方法用它的第一個“this”引數定義它可以呼叫的型別。重要的是要知道,您只能在擴展方法中使用該型別的公共屬性和方法。與通常的靜態方法相同。
泛型
您以前從未見過泛型類,或者只是沒有泛型介面?后者:基本相同,使用時需要指定介面的具體型別。在您的情況下,您可以指定屬性 P 的型別。練習顯示的示例將其指定為 enum Day。如果您從未見過或使用過泛型,您應該首先查看檔案和教程。
話雖如此,您的擴展方法應該有這樣的簽名。
public static void Indexing<T>(this IEnumerable<I<T>> s) where T : Enum
{
...
}
我不確定為什么練習要您使用陣列,因為陣列不能是 C# 中的泛型。我在我的簽名中使用了 IEnumerable。where 陳述句將 T 的可能型別限制為列舉。
測驗
我建議你看看單元測驗來測驗你的實作。一旦你把它坐起來并掌握它,它就非常有幫助。我會推薦 xUnit。NUnit 也很好。我不建議將 Microsoft.VisualStudio.UnitTesting 用于 .net-core 及更高版本。
我希望這會有所幫助,并且不是太多不需要的解決方案:)
uj5u.com熱心網友回復:
我希望您已經熟悉 C# 中的介面或泛型型別的基礎知識!如果沒有,我建議您查看以下資源:
- https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics
- https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface
現在你把這兩個概念混合在一起了。根據您使用 day-enum 的示例IDay,實作該介面的類I<T>可能如下所示:
public enum Day { Mo, Tu, We, Th, Fr }
public class IDay : I<Day>
{
public Day P { get; }
public IDay(Day day)
{
P = day;
}
}
現在,擴展方法是一種方法,它的行為就像是由物件本身的類提供的,但實際上只是另一個靜態類的附錄,為第一個類添加更多功能。它是this引數中的關鍵字來標記它應該擴展哪個類。所以一般結構總是如下所示:
public static class ClassForYourExtensions
{
public static ReturnType ExtensionMethod(this ClassYouWantToExtend obj)
{
// Write code like you are used to in here
}
}
根據您提供的資訊,我們知道您的擴展方法應滿足以下條件:
- 它回傳一個型別的物件
Dictionary<T, I<T>[]> - 它應該擴展/接受一個型別的物件
I<T>[] - 泛型型別
T具有此方法的列舉型別
這意味著我們可以通過以下方式撰寫擴展函式:
public static Dictionary<T, I<T>[]> Indexing<T>(this I<T>[] arr) where T : Enum
我的另一個提示:您可以使用Enum.GetValues()Function 遍歷 enum 的所有值T。所以,在不劇透的情況下,我會像這樣開始這個函式:
public static Dictionary<T, I<T>[]> Indexing<T>(this I<T>[] arr) where T : Enum
{
Dictionary<T, I<T>[]> result = new();
foreach(var element in Enum.GetValues(typeof(T)))
{
// Add values to the result here...
}
return result;
}
關于您的最后一個問題,即測驗,您首先需要實體化一個實作介面的類的陣列(在這種情況下,我將其稱為 IDay,如上例所示),然后您可以簡單地從此元素呼叫 Indexing 擴展函式:
public static void Testing()
{
IDay[] days = new IDay[]
{
new IDay(Day.Mo),
new IDay(Day.Tu),
new IDay(Day.We),
new IDay(Day.Th),
new IDay(Day.Fr)
};
var res = days.Indexing();
}
我希望這有助于更好地了解您必須用于任務的語法和概念:)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/487096.html
上一篇:清潔架構-DTO場所
下一篇:在類定義中使用If陳述句
