2014-02-14 4 views
1

Я пишу новый BOT для ставок на C# для нового API Betfair и для решения некоторых из грехов прошлого BOT, в котором было много циклов и переданных значений методы как параметры, я пытаюсь разбить все как можно больше.Что такое стандартный способ передачи объектов по ссылке в C#

Один метод делает одно и т. Д. Я также хочу определить объект ставки, который содержит всю мою информацию о бегуне/гонке/ставке в начале моего процесса задания ставок и передает его каждому методу (PlaceBet, CancelBet, CheckBetStatus и т. Д.), Где эти значения будут изменены. Я хочу сделать это, поэтому в конце процесса я знаю, что все значения в моем одиночном объекте Bet верны, поскольку на данный момент я использую множество переменных, которые смешиваются по пути.

Как я не проделал много работы, передавая объекты в качестве ссылки в C#, прежде чем я хотел знать стандартный/лучший/официальный/самый быстрый способ передачи объектов по ссылке.

ли я просто сделать что-то вроде этого

public struct Bet = { 
    public long BetID; 
    public double BetAmount; 
    public int MarketID; 
    public string BetStatus; 
} 

public BetfairBOT(){ 
    Bet bet = new Bet; 
    // get info from DB 
    bet.BetID = 10002323; 
    bet.BetAmount = 10.00; 
    bet.MarketID=12342; 
    bet.BetStatus=""; 

    // get current bet status; 
    this.GetBetStatus(ref bet); 

    // if not matched place bet 
    if(bet.BetStatus != "M"){ 
     this.PlaceBet(ref bet); 
    } 

    // save to DB 
    this.SaveBet(ref bet); 
    } 

    private void GetBetStatus(ref Bet bet){ 
    // do some stuff 
    bet.BetStatus = "U"; 
    return; 
    } 

или я должен использовать объект Bet в качестве возвращаемого типа метода и вернуть его каждый раз, например,

// get current bet status; Setting the bet object to the return object which is passed in by reference 
bet = this.GetBetStatus(ref bet); 

private Bet GetBetStatus(ref Bet bet){ 
    // do some stuff 
    bet.BetStatus = "U"; 
    // return my changed object 
    return bet; 
} 

Или я должен это сделать каким-то другим способом?

Также следует использовать параметр «out» вместо «ref»?

Я просто хочу знать «принятый» способ «наилучшей практики» передавать объекты по ссылке и возвращать их, чтобы я не терял никаких данных на этом пути.

Кстати, нет лучшего способа форматировать код в этом редакторе? Я пробовал отступы некоторых конечных скобок, но они просто не хотят быть частью блока кода над ними.

Есть ли [код] теги, которые я мог бы использовать вместо этого?

Благодарим за любую помощь заранее.

Роб

+1

Ну, глядя на ваш код, возможно, вы хотите использовать 'class', а не' struct'. Тогда вам больше не нужно использовать 'ref', потому что классы« всегда »передаются по ссылке. – Luaan

+0

Возможный дубликат [Когда использовать ref vs out] (http://stackoverflow.com/questions/1516876/when-to-use-ref-vs-out) – ken2k

+0

@Luaan - Классы не всегда передаются по ссылке. Если ключевые слова ref (или out) не используются, механизм передачи по умолчанию имеет значение. Когда передается эталон _type_ _ по значению_, копия ссылки передается. –

ответ

4

Если вы действительно не нужно (и знать что вы делаете), не используйте struct с. Используйте class как можно дальше. Ваша жизнь будет проще и будет работать «автоматически» большую часть времени.

3
  1. Не используйте struct, используйте класс для объекта ставки. Структуры являются типами значений и поэтому должны быть неизменными, но вы передаете их и изменяете внутренние значения.

  2. Для чего вы хотите выполнить, вам не нужно «проходить по ссылке». Объекты уже сортируются по ссылке. Помните, что объекты уже являются ссылочными типами. Когда вы создаете объект, он находится где-то в памяти, а переменная содержит адрес памяти этого объекта. Когда вы передаете его методу, адрес памяти копируется в новую переменную, так как C# имеет значение pass-by-value, но переменная указывает на тот же объект.

Вы на самом деле не передаете объект вокруг, вы передаете ссылку на этот объект только вокруг.

+0

Хорошо, приветствия. Поэтому я должен поменять структуру Bet на класс Bet, а затем создать экземпляр этого значения со значениями из моего набора записей БД (БД, выбирает ставки и предоставляет моей службе набор записей ставок, которые необходимо разместить/отменять и т. Д.). Я просто хочу, чтобы Службы Windows Я пишу, чтобы быть немым терминалом, который получает данные из БД (так как это делает всю работу, анализирующую расы/бегуны и решающую, какие ставки ставить), а затем действует по команде (поместить/отменить ставку и т. Д.) До обновляя БД с результатом. Итак, передача объектов моим методам и изменение значений не требует каких-либо специальных параметров? – MonkeyMagix

+0

Точно. Следует иметь в виду, что когда вы говорите «Bet myBet = new Bet(), объект' Bet' создается где-то в памяти, а 'myBet' содержит ссылку на эту ячейку памяти. Поэтому, когда вы передаете метод 'myBet' методу, все, что вы передаете, является ссылкой на объект' Bet'. – dursk

0

У вас возникла эта проблема, потому что вы определяете Bet как struct. Если вы сохраняете ставки в базе данных с помощью первичного ключа, то обычно это класс. (ValueObject vs Entity)

Как только это класс, вам больше не нужно делать все «по ref». Проверьте this вопрос о том, когда использовать структуру. Мое правило: никогда не используйте структуры, если у вас нет оснований для этого.

это не связано с вашим вопросом, но:

Избегайте волшебных строк: bet.BetStatus = "U";. Вы можете использовать константы или (лучше) enum, чтобы избавиться от магических строк. Или вы можете сделать enum частным и использовать методы, такие как 'Bet.HasEnded(), который будет равен Bet.Status == 'E'.

Открытый/Закрытый принцип: // get info from DB. Вероятно, вы получите лучший дизайн, передав Bet на конструктор или с помощью фабрики. С помощью текущего кода вы связываете свой BetfairBOT с вашей базой данных, что затруднит автоматическое тестирование.

+0

Это был просто базовый пример, чтобы показать вам, что я имел в виду. У меня есть отдельные классы для всех моих объектов и кода API и т. Д. Это был просто пример, показывающий, что я заполнял объект Bet со значениями из БД без необходимости писать код. Статусы ставок являются фиксированными строковыми значениями из betfair. M = Match, S = Settled, U = unmatched, L = Lapsed, C = Отменено и т. Д. Я мог бы изменить их на Enum, но какая польза от него получить, если значения никогда не будут собирается измениться? – MonkeyMagix

+0

хорошо, хорошая статья. Поскольку моя текущая структура хранит информацию (в настоящее время) для 2 других структур BetSelectionPrice (у которых есть BackPrice, LayPrice) и MarketInfo (с MarketID, MarketType, MarketStatus), я должен использовать классы для них, даже если в одном экземпляре объектов моей ставки (один вызов метода RunJob) объект Bet будет содержать объект MarketInfo и объект BetSelectionPrice со значениями, которые НЕ ИЗМЕНЯЮТСЯ. E.G цены, marketID, marketStatus не будут меняться в один звонок. Таким образом, они должны быть структурами или объектами. Они небольшие, и значения не изменятся. – MonkeyMagix

+0

'Я могу изменить их на Enum, но какую выгоду я получу от этого, если значения никогда не изменятся?': ** Readability **.Прямо сейчас вы знаете M = Согласовано, но если кто-то присоединяется к команде или после того, как источник укладывается на 6 месяцев, скорее всего, вы уже не знаете, что означает M ** точно **. Когда это перечисление (или константа), вы также можете предоставить комментарий XML, чтобы сообщить разработчику, работающему с вашим источником, некоторые сведения об этом статусе. Что означает «Соответствие», каков статус раньше, каков наиболее вероятный статус после и т. Д. – Laoujin

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