2012-07-26 47 views
1

Lists的.Last()方法只返回一個值。我希望能夠做到這樣的事情。Extend C#List.Last

List<int> a = new List<int> { 1, 2, 3 }; 
    a.Last() = 4; 

這是我在寫一個擴展方法(它不會編譯)

public unsafe static T* mylast<T>(this List<T> a) 
{ 
    return &a[a.Count - 1]; 
} 

就是我想要做的可能的嘗試?

編輯:

這是我想要使用它的一個例子。

shapes.last.links.last.points.last = cursor; //what I want the code to look like 
//how I had to write it. 
shapes[shapes.Count - 1].links[shapes[shapes.Count - 1].links.Count - 1].points[shapes[shapes.Count - 1].links[shapes[shapes.Count - 1].links.Count - 1].points.Count-1] = cursor; 

這就是爲什麼做

shapes[shapes.Count-1] 

是不是一個真正的解決方案。

+6

你爲什麼要寫這種方法? – 2012-07-26 15:39:36

+0

看起來像他想替換最後一個元素 – Les 2012-07-26 15:42:14

+0

你是說你想要一個方法來將列表中的最後一個項目設置爲右側指定的值? – 2012-07-26 15:42:16

回答

1

我推薦Thom Smith的解決方案,但如果您真的想擁有類似財產的訪問權限,爲什麼不使用屬性?

public class MyList<T> : List<T> 
{ 
    public T Last 
    { 
     get 
     { 
      return this[this.Count - 1]; 
     } 
     set 
     { 
      this[this.Count - 1] = value; 
     } 
    } 
} 

使用,如:

var m = new MyList<int> { 1, 2, 3 }; 
m.Last = 4; 
Console.WriteLine(m.Last); 

沒有不安全的代碼,所以最好。此外,它不排除使用LINQ的Last方法(由於它們的使用方式,編譯器可以將兩者區分開來)。

+0

謝謝。你的方法做我想做的語法。我問這個問題的開始,因爲我希望我不必這樣做,但看起來這是最簡單的方法。 – blooop 2012-07-26 16:18:34

-2

你可能會說:如果你玩啊設置的最後一個值:更酷將通過一項新的價值:

public static void SetLast(this List<int> ints, int newVal) 
    { 
     int lastIndex = ints.Count-1; 
     ints[lastIndex] = newVal; 
    } 
+0

錯過了改變數值的觀點。 – 2012-07-26 15:43:36

+0

OP正在設置最後一個值。 – NominSim 2012-07-26 15:43:42

7

只需使用

a[a.Count-1] = 4; 

或編寫擴展方法

a.SetLast(4); 

即使您可以創建一個人造擴展屬性,這也不是一個好主意。如果解決方案涉及不安全的代碼,則這會增加一倍。

+0

對不起,我第一次沒有完全解釋,看到我的編輯。我會研究人造擴展屬性。 – blooop 2012-07-26 15:56:33

2

您可以創建一個擴展方法來設置最後一個元素。

爲簡單起見,這是它會怎樣看沒有錯誤檢查:

public static class ListExtensions 
{ 
    public static void SetLast<T>(this IList<T> source, T value) 
    { 
     source[source.Count - 1] = value; 
    } 
} 

當然,如果你想正確地做到這一點,你也想錯誤檢查:

public static void SetLast<T>(this IList<T> source, T value) 
{ 
    if (source == null) 
    { 
     throw new ArgumentNullException("source"); 
    } 

    if (source.Count == 0) 
    { 
     throw new ArgumentException("cannot be empty", "source"); 
    } 

    source[source.Count - 1] = value; 
} 
+0

當然,在訪問元素之前,您需要檢查'source.Count> 0' ... – Richard 2012-07-26 15:45:43

+0

並且該源不爲空。 – 2012-07-26 15:46:12

5

有在C#中沒有extension properties。但這裏是一個擴展方法,你可以使用:

public static class ListEx 
{ 
    public static void SetLast<T>(this IList<T> list, T value) 
    { 
     if (list == null) 
      throw new ArgumentNullException("list"); 
     if(list.Count == 0) 
      throw new ArgumentException(
       "Cannot set last item because the list is empty"); 

     int lastIdx = list.Count - 1; 
     list[lastIdx] = value; 
    } 

    //and by symmetry 
    public static T GetLast<T>(this IList<T> list) 
    { 
     if (list == null) 
      throw new ArgumentNullException("list"); 
     if (list.Count == 0) 
      throw new ArgumentException(
       "Cannot get last item because the list is empty"); 

     int lastIdx = list.Count - 1; 
     return list[lastIdx]; 
    } 
} 

這裏是如何使用它

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<int> a = new List<int> { 1, 2, 3 }; 
     a.SetLast(4); 
     int last = a.GetLast(); //int last is now 4 
     Console.WriteLine(a[2]); //prints 4 
    } 
} 

如果你願意,你可以調整驗證行爲。

0
public class AdvancedList : List<int> 
{ 
    public int Last 
    { 
     get { return this[Count - 1]; } 
     set 
     { 
      if(Count >= 1) 
       this[Count - 1] = value; 
      else 
       Add(value); 
     } 
    } 
} 

AdvancedList advancedList = new AdvancedList(); 
advancedList.Add(100); 
advancedList.Add(200); 

advancedList.Last = 10; 

advancedList.Last = 11; 
+0

get get ok,但set將在列表底部添加另一個值,而不是交換它。 – Tallmaris 2012-07-26 15:50:14

+0

@Tallmaris我剛剛測試它沒有,請你可以告訴我更多 – HatSoft 2012-07-26 15:55:08

+0

嘗試做var foo = new AdvancedList(); foo.Last = 3;這將增加3.現在做foo.Last = 4,並且在foo,3和4中有兩個元素.Op想要的是交換最後一個元素,所以保持列表的長度相同,但只更改最後一個int。 – Tallmaris 2012-07-26 16:05:20