簡體   English   中英

在C#泛型中,Java通配符的等價物是什么

[英]What is the equivalent of Java wildcards in C# generics

我正在開發一個應用程序,我需要調用泛型類的方法,而不關心實例的實際類型。 像下面的Java代碼:

public class Item<T>{
  private T item;

  public doSomething(){...}
}

...
public void processItems(Item<?>[] items){
 for(Item<?> item : items)
   item.doSomething();
}

當時我很着急,所以我通過使用我需要調用的方法定義一個接口並使泛型類實現它來解決我的問題。

public interface IItem  
{
   void doSomething();
}

public class Item<T> : IItem {
  private T item;

  public void doSomething(){...}
}

...
public void processItems(IItem[] items)
{
 foreach(IItem item in items)
   item.doSomething();
}

這種解決方法工作正常,但我想知道實現相同行為的正確方法是什么。

編輯:

我忘了提到processItems的調用者不知道實際的類型。 實際上,這個想法是作為參數傳遞給processItems的數組可能包含混合類型。 由於在.Net中不可能有這樣的數組,因此使用非泛型基類或接口似乎是唯一的方法。

執行此操作的常規方法是使方法通用:

public void ProcessItems<T>(Item<T>[] items) {
  foreach(Item<T> item in items)
    item.DoSomething();
}

假設調用者知道類型,類型推斷應該意味着他們不必明確指定它。 例如:

Item<int> items = new Item<int>(); // And then populate...
processor.ProcessItems(items);

話雖如此,創建一個指定類型不可知操作的非泛型接口也很有用。 這在很大程度上取決於您的確切用例。

我看到你只想調用一些沒有參數的方法......已經有了一個合同: Action

public void processItems(IEnumerable<Action> actions)
{
  foreach(Action t in actions)
    t();
}

客戶:

List<Animal> zoo = GetZoo();
List<Action> thingsToDo = new List<Action>();
//
thingsToDo.AddRange(zoo
  .OfType<Elephant>()
  .Select<Elephant, Action>(e => e.Trumpet));
thingsToDo.AddRange(zoo
  .OfType<Lion>()
  .Select<Lion, Action>(l => l.Roar));
thingsToDo.AddRange(zoo
  .OfType<Monkey>()
  .Select<Monkey, Action>(m => m.ThrowPoo));
//
processItems(thingsToDo);

在.NET泛型實現中,你無法省略Type Parameters; 這是設計的。 實際上,由於其基於類型擦除的實現,這只能在Java中實現。

您只能使用基本的非泛型接口(想想IEnumerable<T>IEnumerable )。

當我從Java那里移植東西時,我一直在努力解決同樣的問題

if (o instanceof Collection<?>) doSoemthing((Collection<?>)o);

幸運的是,通用的ICollection也是一個非通用的ICollection,如果有人需要將其中的元素視為純對象,它仍然是可能的:

if (o is ICollection) DoSomething((ICollection)o);

這樣,因為我們不關心集合中元素的實際類型,所以我們在這里得到的是對象。 這里有一個注釋:如果集合中包含原始類型(例如int或byte),那么自動裝箱可能會引發性能損失。

繼喬恩的帖子之后。 使方法通用(模板)否定了對這種功能的要求(使用<?>)。 你總是可以將一個類型提供給一個通用的類/函數,如果你不知道你需要什么類型,你可以使有問題的方法/類通用...最終用戶在調用時必須提供一個類型這樣的函數或使用泛型類,代碼能夠編譯...否則你會得到一些編譯器錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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