.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键<>和Action <>无法找到
- 4. 是否可以更改Func <T, bool>委托的泛型类型参数?
- 5. Java对.NET Func <>和Action <>委托最接近的事情是什么?
- 6. 任务<T>和任务在Func委托
- 7. 委托方法参数从IEnumerable <T>到特定类型
- 8. 使用Action委托根据泛型调用正确的函数
- 9. 动作<T> vs委托事件
- 10. C#泛型委托类型推断
- 11. C#委托词典添加
- 12. 如何确定类型是否是Action/Func代表之一?
- 13. Dispatcher.Invoke与Action委托
- 14. 如何检查MethodInfo是否匹配泛型类型T的委托,其中T是Action还是Func?
- 15. 如何创建Func <TSource>到表达式<Func <TSource,TValue >>
- 16. 在C#4.0中将'TimeOut'参数添加到'Func <>'
- 17. 如何将Action <string>添加到界面?
- 18. 类型委托的DependencyProperty
- 19. “所有方法”的C#委托或Func?
- 20. c#委托和抽象类
- 21. CastException试图调用操作<KeyValuePair <>>委托异步
- 22. 事件类型不能是Action <>?
- 23. 如何在列表中添加类型<T> in c#4,0
- 24. 如何使用匿名泛型委托在C#2.0
- 25. .Net-行动<T>委托错误?
- 26. 如何撰写Linq表达式?即Func <Exp <Func<X, Y>>,Exp <Func<Y, Z>>,Exp <Func<X, Z> >>
- 27. 是否有代表结合了Func <T>和Action <T>的功能?
- 28. Func委托与功能
- 29. C#显示错误“委托 'System.Func <...>' 不拿1个参数
- 30. 表达<Func键<T, bool>>谓词两种类型
没有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