以下问题和答案解决了在委托中使用out参数的问题:
我需要更进一步.我有几个转换方法(函数),我想利用一个委托.例如,让我们从下面的示例方法开始:
private bool ConvertToInt(string s, out int value)
{
try
{
value = Int32.Parse(s);
return true;
}
catch (Exception ex)
{
// log error
value = 0;
}
return false;
}
private bool ConvertToBool(string s, out bool value)
{
try
{
value = Convert.ToBoolean(s);
return true;
}
catch (Exception ex)
{
// log error
value = false;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
然后我宣布了以下代表:
delegate V ConvertFunc<T, U, V>(T input, out U output);
Run Code Online (Sandbox Code Playgroud)
我想做的是这样的事情(伪代码):
if (do int conversion)
func …Run Code Online (Sandbox Code Playgroud) 当我有这个,
public static object Create()
{
return new object();
}
Run Code Online (Sandbox Code Playgroud)
这工作:
var m = typeof(Class).GetMethod("Create");
var e = Expression.Call(m);
Func<object> f = Expression.Lambda<Func<object>>(e).Compile();
Run Code Online (Sandbox Code Playgroud)
但是,当我有这个,
public static object Create(Type t)
{
return new object();
}
Run Code Online (Sandbox Code Playgroud)
这失败了:
var m = typeof(Class).GetMethod("Create");
var e = Expression.Call(m, Expression.Parameter(typeof(Type)));
var t = Expression.Parameter(typeof(Foo));
Func<object> f = Expression.Lambda<Func<object>>(e, t).Compile();
Run Code Online (Sandbox Code Playgroud)
我得到System.Core.dll中发生的类型为"System.ArgumentException"的未处理异常.附加信息:为lambda声明提供的参数数量不正确.该参数t只是虚拟类型的表达式Foo.我认为这无关紧要.我在哪里错了?
作为funcletizer的一部分,我希望用它们的计算常量替换不包含参数的c#表达式:
double d = 100.0;
Expression<Func<double, double>> ex1 = x => -x;
Expression<Func<double>> ex2 = () => -d;
Expression result;
result = Funcletize(ex1); // should return ex1 unmodified
result = Funcletize(ex2); // should return Expression.Constant(-100.0)
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过将表达式包装在lambda表达式中并调用它来评估表达式:
object result = Expression.Lambda(ex2).Compile().DynamicInvoke();
// result == -100
Run Code Online (Sandbox Code Playgroud)
当表达式包含未绑定的参数时,ex1如上所述,这当然会失败,抛出InvalidOperationException,因为我没有提供任何参数.如何检查表达式是否包含此类参数?
我当前的解决方案涉及try {} catch(InvoalidOperationException),但这似乎是一种非常不优雅且容易出错的方式:
// this works; by catching InvalidOperationException
public static Expression Funcletize(Expression ex)
{
try
{
// Compile() will throw InvalidOperationException,
// if the expression contains unbound parameters
var lambda = Expression.Lambda(ex).Compile(); …Run Code Online (Sandbox Code Playgroud) 我有一个问题,是否可以(如果是,如何)class从Func<T, TResult>代表内部访问成员.
例如,我有以下内容class:
class NinjaTurtle
{
public string Sound { get; set; }
public Func<string, string> DoNinjaMove { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在我想这样做
NinjaTurtle leonardo = new NinjaTurtle();
leonardo.Sound = "swiishhh!";
leonardo.DoNinjaMove = (move) => {
if(move == "katana slash") return leonardo.Sound;
return "zirp zirp zirp";
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我定义回调函数时,如何正确访问属性Sound?从函数外部使用对实例的引用是否可以?当我将对象传递给另一个方法时,或者当这将成为dll的一部分时,这仍然有用吗?我会从dll中的函数返回对象leonardo吗?它会"生存"序列化/反序列化吗?
(感谢弗拉基米尔和李,这个问题现在更具体到我想知道的内容).
我的代码库中有一些相当复杂的实体框架查询,我决定将逻辑集中到模型中.基本上,描绘了一堆控制器,它们在表达式树中有大量查询和大量重复代码.因此,我取出了部分表达树并将它们移动到模型中,从而减少了重复次数.
例如,假设我经常需要获取名为Entity的模型,这些模型处于Not Deleted状态.在我的实体模型上,我有:
public static Func<Entity, bool> IsNotDeleted = e =>
e.Versions != null ?
e.Versions.OrderByDescending(v => v.VersionDate).FirstOrDefault() != null ?
e.Versions.OrderByDescending(v => v.VersionDate).First().ActivityType != VersionActivityType.Delete :
false :
false;
Run Code Online (Sandbox Code Playgroud)
(这是较小的示例之一,主要是在尝试检查数据之前检查有效数据.)
使用它看起来像:
var entities = EntityRepository.Entities.Where(Entity.IsNotDeleted).Where(...
Run Code Online (Sandbox Code Playgroud)
但是我发现,虽然有时候我想这是不会被删除的记录,其他时间我想要的记录被删除.要做到这一点,有没有办法从消费代码中反转逻辑?概念上类似于此的东西(显然不起作用):
var entities = EntityRepository.Entities.Where(!Entity.IsDeleted).Where(...
Run Code Online (Sandbox Code Playgroud)
我宁愿不在Func<>物体上有两个,一个用于IsDeleted,另一个IsNotDeleted几乎相同.的Func<>回报bool,是否有语法把一个在当它调用它的逆.Where()条款?
以下两个陈述之间有什么区别吗?他们都工作.
if ( ((Func<bool>)(()=>true))() ) { .... };
if ( new Func<bool>(()=>true)()) { .... };
Run Code Online (Sandbox Code Playgroud) 所以这是我在使用表达式和函数时观察到的奇怪行为.
public int Age { get; set; }
public EyeColor EyeColor { get; set; }
public int Weight { get; set; }
public Func<Person, bool> AgeAndEyesMatch
{
get { return IsPersonYoung().Compile() + PersonHasRightEyeColor().Compile(); }
}
public Func<Person,bool> AgeAndWeightMatch
{
get { return IsPersonYoung().Compile() + IsPersonInShape().Compile(); }
}
private Expression<Func<Person, bool>> PersonHasRightEyeColor()
{
return person => person.EyeColor == EyeColor;
}
private Expression<Func<Person, bool>> IsPersonYoung()
{
return person => person.Age <= Age;
}
private Expression<Func<Person, bool>> IsPersonInShape()
{
return person => person.Weight …Run Code Online (Sandbox Code Playgroud) 更新: 我想写做萨姆工作的方法和它实际上这些作品之前,需要经过一定的验证.这些验证取决于它将要做的工作.
经过一番思考之后,我仍然希望使用相同的模式并进行一些细微的更改. 现在,我想使以下代码工作:
SomeClass:
public SomeResponse DoSomething<T>(params Func<T, bool>[] validations)
{
if(validations.All(v=>v(T))
{
some logic..
}
return SomeResponse;
}
Run Code Online (Sandbox Code Playgroud)
用法:
private Func<SomeRequest, bool> ValidateName = r =>
{return !string.IsNullOrWhiteSpace(r.Name);};
private Func<SomeRequest, bool> ValidatePhone = r =>
{return !string.IsNullOrWhiteSpace(r.Phone);};
var someResponse = SomeClass.DoSomething<SomeRequest>(ValidateName,ValidatePhone);
Run Code Online (Sandbox Code Playgroud)
同样,代码目前不起作用,因为它给了我错误
if(validations.All(v=>v(T))
Run Code Online (Sandbox Code Playgroud)
基本上Type参数在这里无效,我找不到将实际SomeRequest对象传递给Func的方法.
我应该如何编写代码来循环遍历函数列表返回的所有结果,并确保它们返回true,以及保持Type参数的灵活性?
回答:
找到了一种方法,希望这可以有所帮助:
只需将方法定义修改为:
SomeClass的:
public SomeResponse DoSomething<T>(T request, params Func<T, bool>[] validations)
{
if(validations.All(v=>v(request))
{
some logic..
}
return SomeResponse;
}
Run Code Online (Sandbox Code Playgroud)
然后使用它像:
var someResponse = …Run Code Online (Sandbox Code Playgroud) 我试图在某些ViewController使用中运行一个函数AppDelegate
func applicationDidBecomeActive(_ application: UIApplication) {
ViewController().grabData()
}
Run Code Online (Sandbox Code Playgroud)
但不知何故,当应用程序从后台进入应用程序后变为活动状态时,该功能似乎根本无法运行.
该功能看起来像这样
func grabData() {
self._DATASERVICE_GET_STATS(completion: { (int) -> () in
if int == 0 {
print("Nothing")
} else {
print(int)
for (_, data) in self.userDataArray.enumerated() {
let number = Double(data["wage"]!)
let x = number!/3600
let z = Double(x * Double(int))
self.money += z
let y = Double(round(1000*self.money)/1000)
self.checkInButtonLabel.text = "\(y) KR"
}
self.startCounting()
self.workingStatus = 1
}
})
}
Run Code Online (Sandbox Code Playgroud)
并使用此var
var money: Double = 0.000
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
谢谢!
如何将例如2个字符串传递给Func并返回一个字符串?假设我要传递FirstName和LastName,结果应类似于FirstName + LastName;
此外,我想将Func声明为属性。
请看一下我的代码:
public class FuncClass
{
private string FirstName = "John";
private string LastName = "Smith";
//TODO: declare FuncModel and pass FirstName and LastName.
}
public class FuncModel
{
public Func<string, string> FunctTest { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
您能帮我解决这个问题吗?