.NET Framework 3.5的推出是非常方便的操作和Func鍵<>預定義的委託類型。是否有條件地將這些委託添加到我的源代碼中,以便它們可以針對.NET 2.0和.NET 3.5進行編譯而不會發生名稱衝突?類似#if未定義(Action)public delegate void Action(); r #if TARGET_FRAMEWORK < 3.5 public delegate void Action();如何正確添加Action和Func <>委託類型到C#2.0?
回答
當你重新定義你的行動和Func鍵代表,他們將在不同的命名空間,因此不與NET 3.5的任何衝突。他們將具有相同的簡單名稱,簽名和用途,但完全限定的名稱會有所不同。所以不要混淆,也不需要PreProcessor指令。
唯一需要注意的是,他們將不同的與.NET 3.5中定義的Action和Func類型不同。他們將工作完全一樣。他們只是不同的類型。例如,如果您想調用採用原始動作類型的3.5 BCL方法,但這會使您陷入麻煩,但是因爲您正在拍攝2.0版本的兼容性,所以不會發生這種情況。
但我需要爲它們使用完全限定的名稱,對吧?如果我同時使用系統 ;使用MyDelegateTypes的 ; 如果使用.NET 3.5目標進行編譯,會導致名稱衝突?或不? – grigoryvp 2009-11-09 15:49:40
編號操作和Func位於基本的System命名空間中,但它們實際上是在System.Core程序集中定義的,您不應該加載該程序集,因爲這會導致2.0編譯出現問題。 – 2009-11-09 15:54:00
我剛剛編譯了一個只使用System的測試代碼;並使用MyDelegates ;.它給編譯錯誤關於System.Action和MyDelegates.Action之間的名稱衝突:( – grigoryvp 2009-11-09 15:58:27
如果你在一個動作<>或者函數<>聲明中的VS中執行「定義」,你會看到如何聲明它們。例如Action聲明如下:
public delegate void Action<T>(T obj);
編輯:檢查.NET的版本我不認爲有任何預定義。但是,您可以爲每個目標版本定義一個構建配置,並在其中定義一個符號。
我知道。但我需要一種方法來聲明它們僅適用於C#2.0,所以如果我的代碼是在c#3.5中編譯的,那麼名稱將不會發生衝突。 – grigoryvp 2009-11-09 15:42:42
你可以它們作爲本地添加到你需要它們的類。
public class MyClass
{
// These were not added until .Net 3.5
public delegate void Action();
public delegate TResult Func<TResult>();
public delegate TResult Func<TResult,T>(T arg);
public delegate TResult Func<TResult,T1, T2>(T1 arg1, T2 arg2);
public void DoSomething(Func<int> callback) {
...
}
}
將它們添加到所有類是很多代碼:(。也許這是一些#if只有當它們還沒有被定義時才允許定義它們。像#if未定義(Func)...或#if COMPILER_VERSION <3.5 ... – grigoryvp 2009-11-09 15:43:48
我找不到你使用預定義的預處理器變量,但你可以很容易地設置一個項目屬性(在Build標籤)。在切換您編譯的.NET版本時,您可以在構建之前將該標誌切換爲任何想要的標誌。
是的,這聽起來很奇怪就像一種解決方案,如果沒有找到更好的東西,我會使用它,但是對於特定的構建而言,特定的預處理器變量會導致構建過程複雜化,這不是一件很好的事情:(. – grigoryvp 2009-11-09 15:52:30
試試這個:
打開你的項目,右鍵單擊您的項目在解決方案資源管理器,導航托特他建立選項卡,在條件編譯符號文本框添加CSHARP2
。
聲明一個類調用CSharpExtensions.cs:
namespace System
{
#if CSHARP2
public delegate void Action();
public delegate void Action<T>(T t);
public delegate void Action<T, U>(T t, U u);
public delegate void Action<T, U, V>(T t, U u, V v);
public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T t);
public delegate TResult Func<T, U, TResult>(T t, U u);
public delegate TResult Func<T, U, V, TResult>(T t, U u, V v);
#endif
}
假設你在3.5 編譯不定義CSHARP2符號,你應該能夠使用上面的功能預期:
using System; // includes our new delegates
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static IEnumerable<U> Map<T, U>(IEnumerable<T> input, Func<T, U> f)
{
foreach (T t in input)
{
yield return f(t);
}
}
static void Main(string[] args)
{
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
foreach(String s in Map<int, string>(numbers, delegate(int i) { return String.Format("{0}^2 = {1}", i, i*i); }))
{
Console.WriteLine(s);
}
Console.ReadLine();
}
}
}
這是.NET 2.0,不是C#2.0,所以命名爲'CSHARP2'是非常具有誤導性的。 – 2009-11-09 16:07:27
我已經使用這個很成功。在.NET 2.0中構建項目時定義FOR_DOTNET2。更妙的是,您可以從MSDN中複製摘要註釋並將其放入XML格式。
#if FOR_DOTNET2
namespace System
{
public delegate void Action<T>(T arg);
}
#endif
- 1. C#Func委託
- 2. Autofac委託工廠使用func <>
- 3. 如何聲明一個返回相同類型的Func委託的Func委託?
- 4. Func鍵<>和Action <>無法找到
- 5. 是否可以更改Func <T, bool>委託的泛型類型參數?
- 6. Java對.NET Func <>和Action <>委託最接近的事情是什麼?
- 7. C#Func <>委託庫中的代碼
- 8. Understadning C#委託Func鍵<...>運營商
- 9. 如何使用Delegate.CreateDelegate而不是Func <>來定義委託?
- 10. 如何正確添加Func到Linq?
- 11. 任務<T>和任務在Func委託
- 12. 如何委託正確的行動<Interface>?
- 13. 使用正確類型調用委託
- 14. 如何實現Action委託?
- 15. 委託方法參數從IEnumerable <T>到特定類型
- 16. 使用Action委託根據泛型調用正確的函數
- 17. Action委託C#到vb.net轉換
- 18. 添加<類型 'datetime.date'>和<類型 'datetime.time'>
- 19. 將多個代理添加到Func <T>並返回第一個lambda委託(C#)的結果?
- 20. 動作<T> vs委託事件
- 21. C#泛型委託類型推斷
- 22. 添加和語句表達<Func鍵<T, bool>>
- 23. C#委託詞典添加
- 24. 如何確定類型是否是Action/Func代表之一?
- 25. Dispatcher.Invoke與Action委託
- 26. 如何檢查MethodInfo是否匹配泛型類型T的委託,其中T是Action還是Func?
- 27. 如何創建Func <TSource>到表達式<Func <TSource,TValue >>
- 28. 在C#4.0中將'TimeOut'參數添加到'Func <>'
- 29. 類型委託的DependencyProperty
- 30. 「所有方法」的C#委託或Func?
沒有C#3.5 - Action和Func <>是.Net 3.5框架中的類型。 C#3.0有一些語法(如var和lambdas)來幫助使用這些類型。 – 2009-11-09 15:45:56
感謝您的評論,我編輯了一個問題來澄清它。 – grigoryvp 2009-11-09 15:47:53