2014-01-28 2 views
0

Хорошо, ребята, я немного смущен этой штукой. Я покажу вам код, с которым у меня проблемы.Передача метода с типом возвращаемого значения в цикле for

Так у меня есть класс CellMap, который имеет этот метод:

public Vector3 GetFreeCell() 
{ 
    Vector3 result = new Vector3(); 

    if (mOccupiedPoint != null) 
    { 
     result = (Vector3)mOccupiedPoint[0]; 

     mOccupiedPoint.RemoveAt(0); 
    } 

    return result; 
} 

Следующая я есть мой класс WorldMap, который имеет этот метод:

private void AddObject(GameObjectBase obj, int times, Vector3 position) 
{ 
    for (int i = 0; i < times; i++) 
    { 
     Vector3 tempPos = position; 

     AddObject(obj, tempPos); 
    } 
} 

Итак, теперь, когда я прохожу для параметра Vector3 GetFreeCell() в моем методе AddObject:

private CellMap mCellMap; 

public WorldMap() 
{ 
    CreateCellMap(100, 1, 100); 

    AddObject(new DarkForestTreeA(), 1000, mCellMap.GetFreeCell()); 

} 

Я получаю то же самое старое значение Vector3 от t он mCellMap.GetFreeCell() я могу изменить метод AddObject(), как:.

private void AddObject(GameObjectBase obj, int times) 
{ 
    for (int i = 0; i < times; i++) 
    { 

     AddObject(obj, mCellMap.GetFreeCell()); 
    } 
} 

, но я хочу, чтобы сохранить параметр Vector3. Может кто-нибудь помочь мне и дать мне подсказку, как заставить метод GetFreeCell() выполнить в цикле for, но передать его только как параметр?

+1

Удаление из передней части 'List' неэффективно, рассмотрите возможность использования очереди или связанного списка. – Lee

+0

Спасибо за совет! –

ответ

3

Ваш вопрос немного запутанный, но если я понимаю, что вы просите, вы хотите, чтобы передать функцию (в данном случае GetFreeCell) к AddObject, который будет вызван times много раз. В этом случае, используйте delegate:

public WorldMap() 
{ 
    CreateCellMap(100, 1, 100); 

    AddObject(new DarkForestTreeA(), 1000, mCellMap.GetFreeCell); // note no() after method name 
} 

private void AddObject(GameObjectBase obj, int times, Func<Vector3> vectorFunc) 
{ 
    for (int i = 0; i < times; i++) 
    { 
     AddObject(obj, vectorFunc()); 
    } 
} 
+0

Да, это именно то, что я искал, но мне кажется, что это было немного проще, чем передача делегата. Я думал, что есть какой-то способ передать его как вектор Vector3 ... –

+0

@MamaTate Если вы передадите 'Vector3' каждый раз через цикл будет один и тот же' Vector3'.Если вы хотите, чтобы каждый раз, когда вы повторяете свой цикл 'for', вам нужен другой' Vector3', вам нужно сделать что-то другое. Делегат, вероятно, является самым чистым решением. –

+0

Звучит как тавтология: «Если я понимаю, что вы просите, вы хотите передать делегат ... В этом случае используйте делегат« _ ;-) –

0

Вы хотите что-то ищите?

private void AddObject(GameObjectBase obj, int times, Vector3 position) 
{ 
    for (int i = 0; i < times; i++) 
    { 
     Vector3 tempPos = mCellMap.GetFreeCell(); 

     AddObject(obj, tempPos); 
    } 
} 
0

Вы не можете передать объект и он просто обновить себя для каждого использования.

Вы можете передать функцию в метод, и использовать, чтобы получить место для каждой итерации:

private void AddObject(GameObjectBase obj, int times, Func<Vector3> getPosition) 
{ 
    for (int i = 0; i < times; i++) 
    { 
     Vector3 tempPos = getPosition(); 

     AddObject(obj, tempPos); 
    } 
} 

Вы можете вызвать его с помощью лямбда-выражения для функции:

AddObject(new DarkForestTreeA(), 1000,() => mCellMap.GetFreeCell()); 

Решение, которое является более сложным, заключается в том, чтобы отправить «магический» объект, который будет использоваться для преобразования в Vector3 при его использовании и каждый раз возвращать новое значение:

public class MagicVector3 { 

    private Func<Vector3> _getVector; 

    public MagicVector3(Func<Vector3> getVector) { 
    _getVector = getVector; 
    } 

    public static implicit operator Vector3(MagicVector3 magic) { 
    return magic._getVector(); 
    } 

} 

Теперь вы можете просто изменить параметр Vector3 в MagicVector3, и вызвать его с помощью:

AddObject(new DarkForestTreeA(), 1000, new MagicVector3(() => mCellMap.GetFreeCell())); 

Этот код имеет немного кода запаха, хотя. Обычно вы не использовали бы такое значение, поскольку оно вроде скрывает то, что на самом деле происходит.

+0

Зачем использовать лямбда, когда вы можете использовать группу методов? – Magus

+0

@ Magus: Хорошая точка. Это было бы прекрасно, я просто не думал об этом. – Guffa

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