2009-11-09 46 views
2

.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?

+0

沒有C#3.5 - Action和Func <>是.Net 3.5框架中的類型。 C#3.0有一些語法(如var和lambdas)來幫助使用這些類型。 – 2009-11-09 15:45:56

+0

感謝您的評論,我編輯了一個問題來澄清它。 – grigoryvp 2009-11-09 15:47:53

回答

1

當你重新定義你的行動和Func鍵代表,他們將在不同的命名空間,因此不與NET 3.5的任何衝突。他們將具有相同的簡單名稱,簽名和用途,但完全限定的名稱會有所不同。所以不要混淆,也不需要PreProcessor指令。

唯一需要注意的是,他們將不同的與.NET 3.5中定義的Action和Func類型不同。他們將工作完全一樣。他們只是不同的類型。例如,如果您想調用採用原始動作類型的3.5 BCL方法,但這會使您陷入麻煩,但是因爲您正在拍攝2.0版本的兼容性,所以不會發生這種情況。

+0

但我需要爲它們使用完全限定的名稱,對吧?如果我同時使用系統 ;使用MyDelegateTypes的 ; 如果使用.NET 3.5目標進行編譯,會導致名稱衝突?或不? – grigoryvp 2009-11-09 15:49:40

+0

編號操作和Func位於基本的System命名空間中,但它們實際上是在System.Core程序集中定義的,您不應該加載該程序集,因爲這會導致2.0編譯出現問題。 – 2009-11-09 15:54:00

+0

我剛剛編譯了一個只使用System的測試代碼;並使用MyDelegates ;.它給編譯錯誤關於System.Action和MyDelegates.Action之間的名稱衝突:( – grigoryvp 2009-11-09 15:58:27

1

如果你在一個動作<>或者函數<>聲明中的VS中執行「定義」,你會看到如何聲明它們。例如Action聲明如下:

public delegate void Action<T>(T obj); 

編輯:檢查.NET的版本我不認爲有任何預定義。但是,您可以爲每個目標版本定義一個構建配置,並在其中定義一個符號。

+0

我知道。但我需要一種方法來聲明它們僅適用於C#2.0,所以如果我的代碼是在c#3.5中編譯的,那麼名稱將不會發生衝突。 – grigoryvp 2009-11-09 15:42:42

0

你可以它們作爲本地添加到你需要它們的類。

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) { 
     ... 
    } 
} 
+0

將它們添加到所有類是很多代碼:(。也許這是一些#if只有當它們還沒有被定義時才允許定義它們。像#if未定義(Func)...或#if COMPILER_VERSION <3.5 ... – grigoryvp 2009-11-09 15:43:48

1

我找不到你使用預定義的預處理器變量,但你可以很容易地設置一個項目屬性(在Build標籤)。在切換您編譯的.NET版本時,您可以在構建之前將該標誌切換爲任何想要的標誌。

+0

是的,這聽起來很奇怪就像一種解決方案,如果沒有找到更好的東西,我會使用它,但是對於特定的構建而言,特定的預處理器變量會導致構建過程複雜化,這不是一件很好的事情:(. – grigoryvp 2009-11-09 15:52:30

3

試試這個:

打開你的項目,右鍵單擊您的項目在解決方案資源管理器,導航托特他建立選項卡,在條件編譯符號文本框添加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(); 
     } 
    } 
} 
+3

這是.NET 2.0,不是C#2.0,所以命名爲'CSHARP2'是非常具有誤導性的。 – 2009-11-09 16:07:27

1

我已經使用這個很成功。在.NET 2.0中構建項目時定義FOR_DOTNET2。更妙的是,您可以從MSDN中複製摘要註釋並將其放入XML格式。

#if FOR_DOTNET2 
namespace System 
{ 
    public delegate void Action<T>(T arg); 
} 
#endif 
相關問題