为什么Func<>
从Expression<Func<>>
via .Compile()创建的文件比直接使用Func<>
声明要慢得多?
我刚刚使用Func<IInterface, object>
声明直接更改为Expression<Func<IInterface, object>>
在我正在处理的应用程序中创建的一个,我注意到性能下降了.
我刚做了一点测试,Func<>
从一个Expression创建的"几乎"是Func<>
直接声明的时间的两倍.
在我的机器上,Direct Func<>
大约需要7.5秒,Expression<Func<>>
大约需要12.6秒.
这是我使用的测试代码(运行Net 4.0)
// Direct
Func<int, Foo> test1 = x => new Foo(x * 2);
int counter1 = 0;
Stopwatch s1 = new Stopwatch();
s1.Start();
for (int i = 0; i < 300000000; i++)
{
counter1 += test1(i).Value;
}
s1.Stop();
var result1 = s1.Elapsed;
// Expression . Compile()
Expression<Func<int, Foo>> expression = x => new Foo(x …
Run Code Online (Sandbox Code Playgroud) 没有发射了反光看差异,但人们所期望看到比较时完全一样的编译代码Func<T, bool>
与Predicate<T>
我认为没有区别,因为它们都采用通用参数并返回bool?
Autofac自动生成工厂Func<T>
; 我甚至可以传递参数.
public class MyClass
{
public MyClass(Func<A> a, Func<int, B> b)
{
var _a = a();
var _b = b(1);
}
}
Run Code Online (Sandbox Code Playgroud)
我可以和Ninject一样吗?如果没有,我可以申请哪种解决方法?
谢谢.
更新:
刚发现这篇帖子,似乎答案是否定的:
我已经读过,扩展System.Object通常是不好的做法,我同意这一点.
但是,如果以下内容被认为是一种有用的扩展方法,或者它仍然是不好的做法,我很好奇吗?
它类似于扩展System.Object但不完全相同,
public static R InvokeFunc<T, R>(this T input, Func<T, R> func)
{
return func.Invoke(input);
}
Run Code Online (Sandbox Code Playgroud)
这实际上允许任何对象调用任何将该对象作为参数并返回R的函数,无论该函数是否属于该对象.我认为这可能有助于一些有趣的"控制反转",但总体上并不确定.
思考?
我现在一直在看Func <>,我已经设法避免它(现在).但是,现在看起来我无法永远避开它.例如,我尝试了Dynamic Linq,但几乎所有内容都是以Func <>为例.我已经尝试过我的一本书(C#2008/Deitel&Deitel)和MSDN,但我还没有得到它.他们都直接跳入主题.
谢谢你的帮助
我篡改了表达式,我在某些方面感到困惑
我们可以将相同的LamdaExpression分配给Expression和/或Func.但我们不能将Func分配给表达式(或表达式为Func).为什么我们不能这样做?我查找是否定义了Expression和Func之间的转换运算符但我找不到任何转换运算符.
Func<int, int> sumFunc = i => i + i;
Expression<Func<int, int>> sumExp = i => i + i;
// sumExp = sumFunc; // Cannot convert source type 'System.Func<int,int>' to target type 'System.Linq.Expressions.Expression<System.Func<int,int>>'
// sumFunc = sumExp; // Cannot convert source type 'System.Linq.Expressions.Expression<System.Func<int,int>>' to target type 'System.Func<int,int>'
Run Code Online (Sandbox Code Playgroud)即使我们无法将LambdaExpression分配给对象.再说一遍,为什么我们不能这样做呢?
// object o = i => i + i; // Cannot convert source type 'lambda expression' to target type 'object'
Run Code Online (Sandbox Code Playgroud)我认为编译器有一些东西.如果是这样,我们可以编写那些以这种(令人困惑的)方式表现的自定义类型并利用某些东西.
假设我有类:
public class Order
{
int OrderId {get; set;}
string CustomerName {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
我也在下面声明了变量
Func<Order, bool> predicate1 = t=>t.OrderId == 5 ;
Func<Order, bool> predicate2 = t=>t.CustomerName == "Ali";
Run Code Online (Sandbox Code Playgroud)
是否有任何方法可以连接这些变量(使用AND/OR)并将结果放在第三个变量中?例如:
Func<Order, bool> predicate3 = predicate1 and predicate2;
Run Code Online (Sandbox Code Playgroud)
要么
Func<Order, bool> predicate3 = predicate1 or predicate2;
Run Code Online (Sandbox Code Playgroud) 我正在使用FluentValidation,我想格式化一个对象的属性值的消息.问题是我对C#中的表达式和委托的经验很少.
FluentValidation已经提供了一种使用格式参数执行此操作的方法.
RuleFor(x => x.Name).NotEmpty()
.WithMessage("The name {1} is not valid for Id {0}", x => x.Id, x => x.Name);
Run Code Online (Sandbox Code Playgroud)
我想做这样的事情,以避免在我更改参数的顺序时更改消息字符串.
RuleFor(x => x.Name).NotEmpty()
.WithMessage("The name {Name} is not valid for Id {Id}",
x => new
{
Id = x.Id,
Name = x.Name
});
Run Code Online (Sandbox Code Playgroud)
原始方法签名如下所示:
public static IRuleBuilderOptions<T, TProperty> WithMessage<T, TProperty>(
this IRuleBuilderOptions<T, TProperty> rule, string errorMessage,
params Func<T, object>[] funcs)
Run Code Online (Sandbox Code Playgroud)
我在考虑为这个方法提供一个Func列表.
有人可以帮我这个吗?
这是一个冗长的问题,所以请耐心等待.
我需要在一组字符串和每个字符串的相应泛型方法调用之间创建一个映射.但是我遇到了一个编译问题,向下解释.
在我的场景中,我正在使用a Dictionary<>
,但问题同样存在于a List<>
.为简单起见,我List<>
在下面的示例中使用了a .
考虑这三个类:
public abstract class MyBase { /* body omitted */ }
public class MyDerived1 : MyBase { /* body omitted */ }
public class MyDerived2 : MyBase { /* body omitted */ }
Run Code Online (Sandbox Code Playgroud)
还有一些其他类的方法:
public class Test
{
public T GetT<T>() where T : MyBase { /* body omitted */ }
}
Run Code Online (Sandbox Code Playgroud)
在另一个课程中,我可以声明List<Func<MyBase>>
如下:
public class SomeClass
{
public void SomeFunc()
{
var test = new Test();
var list1 …
Run Code Online (Sandbox Code Playgroud) 我是C#的新手.只是玩弄它.不是出于真正的目的.
void makeOutput( int _param)
{
Console.WriteLine( _param.ToString());
}
//...
// Somewhere in a code
{
makeOutput( /* some not c# code for an example for what do I want */ function : int () { return 0; } );
}
Run Code Online (Sandbox Code Playgroud)
是否可以使用REAL匿名函数(意味着返回结果)?
我不想使用像这样的代表
// Somewhere in a code
{
Func<int> x = () => { return 0; };
makeOutput( x())
}
Run Code Online (Sandbox Code Playgroud)
另外我不想改变方法参数类型,如
void makeOutput( Func<int> _param)
{
}
Run Code Online (Sandbox Code Playgroud)
这是非常普遍的决定.
一切正常.我只是明白我想要不可能的东西.我想声明匿名函数并在同一个地方执行它.注意:DIRECT声明和DIRECT调用没有通用包装.
// flash-like (as3) code /// DOES NOT COMPILE
makeOutput( (function …
Run Code Online (Sandbox Code Playgroud)