首页 文章

如何正确地将Action和Func <>委托类型添加到C#2.0?

提问于
浏览
2

.NET framework 3.5引入了非常方便的Action和Func <>预定义委托类型 . 是否可以有条件地将这些委托添加到我的源代码中,以便它们可以编译.NET 2.0和.NET 3.5而不会出现名称冲突?像#if未定义的东西(Action)public delegate void Action(); r #if TARGET_FRAMEWORK <3.5 public delegate void Action();

6 回答

  • 1

    重新定义Action和Func委托时,它们将位于不同的名称空间中,因此不会与.Net 3.5中的任何名称冲突 . 它们具有相同的简单名称,签名和目的,但完全限定的名称不同 . 因此不需要任何混淆,也不需要PreProcessor指令 .

    唯一需要注意的是,它们与.Net 3.5中定义的Action和Func类型不同 . 它们的工作方式完全相同 . 他们'll just be different types. This could get you into trouble if you want to call a 3.5 BCL method that takes the original Action type, for example, but since you'重新拍摄2.0兼容性,这是不应该发生的 .

  • 0

    试试这个:

    打开项目,在解决方案资源管理器中右键单击项目,导航到Build选项卡,在条件编译符号文本框中添加 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();
            }
        }
    }
    
  • 1

    如果在Action <>或Func <>声明中对VS执行“转到定义”,您将看到如何声明它们 . 例如,Action声明如下:

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

    编辑:检查.NET的版本我不认为有任何预定义 . 但是,您可以为每个目标版本定义构建配置,并在那里定义符号 .

  • 3

    我找不到预定义的预处理器变量供你使用,但是你可以在项目属性中轻松设置一个(在Build选项卡中) . 在切换编译的.NET版本时,可以在构建之前将该标志切换为您想要的任何标志 .

  • 1

    我用这个非常成功 . 在为.NET 2.0构建项目时定义FOR_DOTNET2 . 更好的是,您可以从MSDN复制摘要注释并将它们以XML格式存储 .

    #if FOR_DOTNET2
    namespace System
    {
        public delegate void Action<T>(T arg);
    }
    #endif
    
  • 1

    您可以将它们作为本地添加到您需要它们的类中 .

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

相关问题