对不起,如果这是基本的,但我试图接受.Net 3.5.
问题:Func <>有什么好处,它有5个重载吗?从它的外观来看,我仍然可以自己创建一个类似的delgate,MyFunc <>具有5个重载甚至更多.
例如:public delegate TResult MyFunc
和各种超载的组合......
当我试图理解Func <>委托并且遇到以下情况时,想到了这个想法:
FuncmyDelegate = (y) => IsComposite(10);
这意味着一个委托有一个int类型的参数和一个int类型的返回类型.有五种变体(如果你通过intellisense查看重载).所以我猜我们可以有一个没有返回类型的委托?
所以我有理由说Func <>不是很好,只是我们可以使用的.Net框架中的一个例子,如果需要,创建自定义"func <>"代表以满足我们自己的需求?
谢谢,
伟大之处在于建立共享语言以促进更好的沟通.
不要为同一事物(委托爆炸)定义自己的委托类型,而是使用框架提供的委托类型.任何阅读你的代码的人都会立即掌握你想要完成的任务.最大限度地减少"这段代码实际上做了什么?"的时间.所以,一看到一个
Action =一些只执行某些操作并且不返回任何输出的方法
比较 =一种比较两个相同类型的对象并返回一个int来表示顺序的方法
Converter =将Obj A转换为等效的Obj B.
EventHandler =某个对象引发的事件的响应/处理程序,它以事件参数的形式给出一些输入
Func =一些接受一些参数,计算某些东西并返回结果的方法
谓词 =根据某些条件评估输入对象,并将通过/失败状态返回为bool
除非是我直接关注的领域,否则我不必深入挖掘.因此,如果您觉得您需要的代表满足其中一个需求,请在使用它们之前使用它们.
免责声明:就个人而言,我喜欢语言设计师的这一举动.
反驳:有时定义你的代表可能有助于更好地传达意图.例如System.Threading.ThreadStart
结束System.Action
.所以这最终是一个判断.
该Func
代表(和他们的回归型少表兄弟,家庭Action
)并不比其他任何你想在.NET framework中发现任何更大.它们只是在那里重复使用,所以你不必重新定义它们.它们具有类型参数以保持通用性.例如,Func
您应该能够只使用内置Func
委托用于任何接受最多4个参数的值返回方法,而不是为此目的定义您自己的委托,除非您希望该名称反映您的意图,这很酷.
您绝对需要定义委托类型的情况包括接受4个以上参数的方法,带有out,ref或params参数的方法,或递归方法签名(例如delegate Foo Foo(Foo f)
).
除了马克思主义者的正确答案:
Action
代表们值得了解Func的相关家庭.同样,这些类型是由类型参数的数量重载,但声明为返回void.
如果您想使用功能/动作在.NET 2.0的项目,但有一个简单的路由升级后,您可以剪切和粘贴我的声明版本比较页面.如果您在声明它们System
的名称空间,那么你就可以通过移除后的声明只是升级-但是你将不能够(容易)建立.NET 3.5相同的代码而不删除的声明.
解耦依赖关系和不友好的合作是一个非常好的事情.其他任何人都可以辩论并声称可以用一些本土的方式来做.
我一直在使用旧的和重的lib重构稍微复杂的系统,并因无法破坏编译时依赖性而被阻止 - 因为命名的委托潜伏在"另一边".所有程序集加载和反射都没有帮助 - 编译器会拒绝将委托(){...}强制转换为对象,而无论你做什么来安抚它都会在另一方面失败.
在编译时结构化的委托类型比较在此之后变为名义上的(加载,调用).当你想到"我亲爱的lib将永远被所有人使用"时,这看起来似乎没问题,但它不能扩展到更复杂的系统.Fun <>模板将一定程度的结构等同性带回到名义类型的世界中.这是你推出自己无法实现的方面.
示例 - 转换:
class Session ( public delegate string CleanBody(); // tying you up and you don't see it :-) public static void Execute(string name, string q, CleanBody body) ...
至:
public static void Execute(string name, string q, Funcbody)
允许完全独立的代码执行反射调用,如:
Type type = Type.GetType("Bla.Session, FooSessionDll", true); MethodInfo methodInfo = type.GetMethod("Execute"); Funcd = delegate() { .....} // see Ma - no tie-ups :-) Object [] params = { "foo", "bar", d}; methodInfo.Invoke("Trial Execution :-)", params);
现有代码没有注意到差异,新代码没有依赖 - 地球上的和平:-)