我想要一个具有以下API的方法:
//get all users with a role of admin
var users = myRepository.GetUsers(u => u.Role == Role.Admin);
Run Code Online (Sandbox Code Playgroud)
这样的事情会起作用吗?
IList<User> GetUsers(Func<User, bool> predicate)
{
var users = GetAllUsers();
return users.Where(predicate).ToList();
}
Run Code Online (Sandbox Code Playgroud)
如果是这样,我将能够指定更复杂的谓词,如(伪代码):
myRepository.GetUsers(u => u.CreatedDate is upto 14 days old);
Run Code Online (Sandbox Code Playgroud) 试图对构造函数接受Func的类进行单元测试.不知道如何使用Moq模拟它.
public class FooBar
{
public FooBar(Func<IFooBarProxy> fooBarProxyFactory)
{
_fooBarProxyFactory = fooBarProxyFactory;
}
}
[Test]
public void A_Unit_Test()
{
var nope = new Mock<Func<IFooBarProxy>>();
var nope2 = new Func<Mock<IFooBarProxy>>();
var fooBar = new FooBar(nope.Object);
var fooBar2 = new FooBar(nope2.Object);
// what's the syntax???
}
Run Code Online (Sandbox Code Playgroud) 有没有办法Func<>动态设置类型参数,所以我不必使用无穷无尽的if语句?
就像是:
Type t = Type.GetType("System.Decimal");
Func<t> foo = new Func<t>(some_function);
Run Code Online (Sandbox Code Playgroud)
代替:
Func<Decimal> foo = new Func<Decimal>(some_function);
Run Code Online (Sandbox Code Playgroud)
更新:
这是我代码中的代码段:
Type t = typeof(StavkaDokumenta).GetProperty(pd.Polje).PropertyType;
ParameterExpression pe = Expression.Parameter(typeof(StavkaDokumenta), "stavka");
Expression expr = Expressions.ResolveCompleteExpression(pe, pd.Expression);
Expression final = Expression.Convert(expr, t);
if (t == typeof(decimal))
{
var lambda = Expression.Lambda<Func<StavkaDokumenta, decimal>>(final, pe);
o = lambda.Compile().Invoke(stavka);
}
if (t == typeof(decimal?))
{
var lambda = Expression.Lambda<Func<StavkaDokumenta, decimal?>>(final, pe);
o = lambda.Compile().Invoke(stavka);
}
else if (t == typeof(int))
{
var lambda …Run Code Online (Sandbox Code Playgroud) 所以我使用以下实用程序从类的实例中获取字段/属性的名称...
public static string FieldName<T>(Expression<Func<T>> Source)
{
return ((MemberExpression)Source.Body).Member.Name;
}
Run Code Online (Sandbox Code Playgroud)
这允许我执行以下操作:
public class CoolCat
{
public string KaratePower;
}
public class Program
{
public static Main()
{
public CoolCat Jimmy = new CoolCat();
string JimmysKaratePowerField = FieldName(() => Jimmy.KaratePower);
}
}
Run Code Online (Sandbox Code Playgroud)
当我需要字段名称的字符串表示时,这非常适合序列化和其他时间.
但是现在,我希望能够获得字段名称而没有类的实例 - 例如,如果我正在设置一个表并希望将列的FieldNames动态链接到类中的实际字段(因此重构)等等不会破坏它).
基本上,我觉得我还没有完全掌握如何实现这一点的语法,但我想它会看起来像这样:
public static string ClassFieldName<T>(Func<T> PropertyFunction)
{
// Do something to get the field name? I'm not sure whether 'Func' is the right thing here - but I would imagine that it is something where …Run Code Online (Sandbox Code Playgroud) 1:
Func<int, int> myFunc = new Func<int,int>(delegate(int x) {
return x + 1;
});
Run Code Online (Sandbox Code Playgroud)
2:
Func<int, int> myFunc = delegate(int x) {
return x + 1;
};
Run Code Online (Sandbox Code Playgroud)
3:
Func<int, int> myFunc = x => x + 1;
Run Code Online (Sandbox Code Playgroud)
他们之间有什么区别?
我正在尝试使用.Net闭包将函数的方法名称传递给对象,如下所示:
方法签名
public IEnumerable<T> GetData<T>(Func<IEnumerable<T>> WebServiceCallback)
where T : class
{
// either gets me '<LoadData>b__3'
var a = nrdsWebServiceCallback.Method.Name;
var b = nrdsWebServiceCallback.GetInvocationList();
return WebServiceCallback();
}
Run Code Online (Sandbox Code Playgroud)
我这样称呼它:
SessionStateService.Labs = CacheManager.GetData(() =>
WCFService.GetLabs(SessionStateService.var1, SessionStateService.var2));
Run Code Online (Sandbox Code Playgroud)
看到'b__3'而不是WCFServce.GetLabs(..)等
我有一个类型的变量,Func<dynamic>我试图给它一个值.如果我将它分配给返回值类型的方法(例如int),我会得到错误
'int MethodName()'的返回类型错误
但是,如果我将方法包装在lambda调用中,它可以正常工作.返回引用类型的方法似乎也可以正常工作.
private string Test()
{
return "";
}
private int Test2()
{
return 0;
}
Func<dynamic> f = Test; // Works
Func<dynamic> g = Test2; // Does not
Func<dynamic> h = () => Test2(); // Works
Run Code Online (Sandbox Code Playgroud)
直接转让案有什么问题?
我需要更深入地了解Func类型表达式.
public class TheResult : IResultEntry {
...
}
Run Code Online (Sandbox Code Playgroud)
上面的类,为什么下面的第二种方法需要演员?
我当然可以阅读错误信息,但很难理解.
// Success
public Task<IResultEntry> ProcessAsync_1()
{
return Task.Factory.StartNew(() => (IResultEntry) new TheResult());
}
// Fail: Compiler error. Cannot implicitly convert...
public Task<IResultEntry> ProcessAsync_2()
{
return Task.Factory.StartNew(() => new TheResult());
}
Run Code Online (Sandbox Code Playgroud)
如果我们在ReSharper的帮助下将其更改为命名方法,我们可以不进行强制转换.
public Task<IResultEntry> ProcessAsync_2_Changed()
{
return Task.Factory.StartNew(function);
}
private IResultEntry function()
{
return new TheResult();
}
Run Code Online (Sandbox Code Playgroud) 从C#7.0开始,throw关键字既可以用作表达式,也可以用作语句,这很好.但是,请考虑这些过载
public static void M(Action doIt) { /*use doIt*/ }
public static void M(Func<int> doIt) { /*use doIt*/ }
Run Code Online (Sandbox Code Playgroud)
在调用时这样
M(() => throw new Exception());
Run Code Online (Sandbox Code Playgroud)
或者甚至喜欢这样(带有语句lambda)
M(() => { throw new Exception(); });
Run Code Online (Sandbox Code Playgroud)
编译器选择M(Func <>)重载,指示throw在这里被视为表达式.如何优雅和明确地强制编译器选择M(Action)重载?
一种方法是这样做
M(() => { throw new Exception(); return; });
Run Code Online (Sandbox Code Playgroud)
但返回语句的原因似乎并不明显,并且存在被下一个开发人员更改的风险,特别是因为Resharper警告无法访问的代码.
(当然我可以更改方法命名以避免重载,但这不是问题.:-)
我有一个带有此堆栈的名为 MyWatchView 的 SwiftUI 视图:
VStack (alignment: .center)
{
HStack
{
Toggle(isOn: $play)
{
Text("")
}
.padding(.trailing, 30.0)
.hueRotation(Angle.degrees(45))
if play
{
MyWatchView.self.playSound()
}
}
}
Run Code Online (Sandbox Code Playgroud)
它还具有如下@State private var play = false功能playSound:
static private func playSound()
{
WKInterfaceDevice.current().play(.failure)
}
Run Code Online (Sandbox Code Playgroud)
我收到一个错误,Type '()' cannot conform to 'View'; only struct/enum/class types can conform to protocols我认为这可能是我不理解结构在 Swift 中的工作方式。