2014-10-28 4 views
0

Я имею recently learned как использовать лямбда для ленивых вычислений, что позволяет мне сделать это:Ленивый оценки в сеттер

MoveTo moveToTargetCreature = 
    new MoveTo(() => parent.Context.TargetCreature); 

...

public class MoveTo 
{ 
    Func<Creature> Target { get; set; } 

    public MoveTo(Func<Creature> Target) 
    { 
     this.Target = Target; 
    } 

    public Act(Creature parent) 
    { 
     parent.MoveTowards(Target().Position); 
    } 
} 

... и вызов подпрограммы Действие() позже, чтобы заставить существо перемещаться к любой ближайшей цели.

Это прекрасно работает, когда все, что я пытаюсь сделать, это получить переменную (просто вызвать Target()), но что, если я хочу ее установить? Например:

SetVariable setTargetCreatureToClosestCreature = 
    new SetVariable(parent.Context.TargetCreature,() => parent.Context.ClosestCreature); 

...

public class SetVariable 
{ 
    Creature VariableToSet { get; set; } 
    Func<Creature> Target { get; set; } 

    public SetVariable(Creature VariableToSet, Func<Creature> Target) 
    { 
     this.VariableToSet = VariableToSet; 
     this.Target = Target; 
    } 

    public Act(Creature parent) 
    { 
     VariableToSet = Target(); 
     //What I want: Set "parent.Context.TargetCreature" to Target() 

     //What it does: Sets the internal "VariableToSet" to Target(), but 
     //leaves "parent.Context.TargetCreature" as what it was when initialised. 
    } 
} 

И если я в качестве альтернативы использовать Func и синтаксис лямбда, он не будет компилироваться, так как вы не можете назначить для вызова метода.

Каким будет подходящий синтаксис для этого?

+2

0 Я пытаюсь понять, что вы пытаетесь сделать здесь. Можете ли вы описать реальную проблему, которую вы пытаетесь решить здесь? – Enigmativity

+0

Приношу свои извинения. Показанный код на самом деле является проблемой, которую я пытаюсь решить, но я добавил пояснение к комментарию в последнем блоке кода, который должен помочь. – Quasar

+0

Нет, я не согласен. Показанный код не является проблемой, которую вы пытаетесь решить. Это ваше предлагаемое решение, которое, по вашему мнению, решит вашу настоящую проблему. Какова ваша реальная проблема? – Enigmativity

ответ

1

Возможно, это то, что вы хотите?

public class SetVariable 
{ 
    Creature ObjectToSet { get; set; } 
    Action<Creature, Creature> SetterAction { get; set; } 

    public SetVariable(Creature objectToSet, Action<Creature, Creature> setterAction) 
    { 
     this.ObjectToSet = objectToSet; 
     this.SetterAction = setterAction; 
    } 

    public Act(Creature parent) 
    { 
     this.SetterAction(parent, this.ObjectToSet); 
     //the setter action would be defined as (when instantiating this object): 
     //SetVariable mySet = new SetVariable(null, (target, val) => target.PropertyName = val); 
     //it will set the PropertyName property of the target object to val (in this case val=null). 
    } 
} 
+0

Да, чтение на Action теперь похоже, что мне нужно. Конечно, мне нужно будет сделать некоторые эксперименты, но я думаю, что с этим могу получить что-то довольно элегантное. – Quasar

+0

Хорошо, но, пожалуйста, подумайте, что я не думаю, что это хорошо с точки зрения архитектуры, чтобы использовать делегатов (в смысле указателей действий/функций) таким образом. По сути, если вы хотите установить свойство X объекта y в значение val, я советую вам сделать именно это: 'y.X = val;'. Кодекс, который делегирует много, очень нечитабелен, и есть лучшие способы выполнить эту функциональность. Если вы опубликуете вопрос с более широкими функциональными требованиями, я с удовольствием посмотрю. –

Смежные вопросы