создание объекта c # looping - PullRequest
1 голос
/ 21 июля 2009

Я очень новичок в c # и ранее пытался игнорировать классы и создавать свою небольшую программу, структурно более похожую на PHP. Добравшись до блокпоста, я пытаюсь начать все заново и правильно подойти к проблеме ОО. Я беру длинный файл и в цикле, каждый раз, когда выполняются определенные условия, я хочу создать новый объект. Как я могу создать новый объект без указания уникального имени?

Referral ObjectName = new Referral(string, string, int);

Во-вторых, как только это будет сделано, и строки & int установят соответствующие свойства объекта, как я могу уникально определить класс по одному свойству, а затем отсортировать класс по другому?

Извините, если это базовые вопросы, я потратил много времени, пытаясь сначала разобраться в этом с помощью Google и учебника. Если бы только C # допускал использование многомерных массивов разных типов!

Большое спасибо!

PS. Я хочу извлечь список уникальных объектов.

Все эти ответы, хотя и полезны, похоже, включают создание теневого набора IEnumerables. Нет ли способа сделать это с самим классом?

При попытке первого решения, предоставленного Earwicker, при добавлении каждого объекта в список из цикла, когда я пытаюсь записать свойство элемента в консоль, я получаю ClassName + Referral. Что я могу делать не так? - решили. все еще нужен .property

все еще работает. , .

Ответы [ 7 ]

7 голосов
/ 21 июля 2009

C # допускает нетипизированные массивы. Все объекты в конечном итоге получены из object, поэтому вы используете массив или контейнер object s. Но это редко необходимо. Сколько у вас типов объектов?

Внутри блока цикла вы можете создать объект точно так же, как вы делаете в этой строке кода (за исключением фиксированного синтаксиса), и он будет новым объектом каждый раз вокруг цикла. Чтобы сохранить все объекты вне цикла, вы должны добавить его в контейнер:

List<Referral> referrals = new List<Referral>();

// in the loop:
Referral r = new Referral(str1, str2, num1);
referrals.Add(r);

Предположим, что Referral имеет числовое свойство с именем Cost.

referrals.Sort((l, r) => l.Cost - r.Cost);

Это сортирует по стоимости.

Для обеспечения уникальности по некоторому ключу вам может быть проще выбрать более подходящий контейнер.

Dictionary<string, Referral> referrals = new List<Referral>();

// in the loop:
Referral r = new Referral(str1, str2, num1);
referrals[str1] = r;

Сохраняет реферал в «слоте», названном в честь значения str1. Дубликаты будут молча перезаписывать друг друга.

3 голосов
/ 21 июля 2009

Во-первых, вам нужно потратить некоторое время на ознакомление с основами языка, чтобы быть продуктивным. Я рекомендую вам уделить немного времени чтению на C #, прежде чем углубляться - в противном случае вы потратите много времени на раскручивание колес или переизобретение их:)

Но вот некоторая информация, с чего можно начать.

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

Вы можете легко создать класс Referall в C #, используя автоматические свойства и простой конструктор:

public class Referall
{
   // these should be named in line with what they represent...
   public string FirstString   { get; set; }
   public string AnotherString { get; set; }
   public int    SomeValue     { get; set; }

   public Referall( string first, string another, int value )
   {
       FirstString = first;
       AnotherString = another;
       SomeValue = value;
   }
}

Вы можете добавлять их в словарь по мере их создания - в словарь можно вводить, какое свойство всегда является уникальным. Словари позволяют хранить объекты на основе уникального ключа:

Dictionary<string,Referall> dict = new Dictionary<string,Referall>();

По мере обработки предметов вы можете добавлять их в словарь:

Referall ref = new Referall( v1, v2, v3 );
// add to the dictionary, keying on FirstString...
dict.Add( ref.FirstString, ref );

Если вам нужно отсортировать элементы в словаре, когда вы закончите, вы можете использовать LINQ в C # 3.0:

IEnumerable<Referall> sortedResults =
       dict.Values.OrderBy( x => x.AnotherString );

Вы также можете сортировать по нескольким измерениям, используя ThenBy ():

IEnumerable<Referall> sortedResults =
       dict.Values.OrderBy( x => x.AnotherString )
                  .ThenBy( x => x.SomeValue );
2 голосов
/ 21 июля 2009
List<Referral> referrals = new List<Referral>();

for (...)
{
    referrals.Add(new Referral(string1, string2, number1));
}

Затем, если вы используете Linq (что я настоятельно рекомендую), вы можете сделать это:

IEnumerable<Referral> sorted = referrals.OrderBy(x => x.string1).ThenBy(x => x.string2);

В противном случае вы можете использовать метод Sort () в Списке .

1 голос
/ 21 июля 2009

Вы можете создать объект без ссылки, но у вас не будет доступа к нему позже:

new Referral(string, string, int);

Если вы хотите поместить их в массив / список, эти разные типы должны иметь общий базовый класс. Это называется полиморфизмом, который является очень важной концепцией в ОО-программировании.

0 голосов
/ 21 июля 2009

C # включает замечательную функцию под названием «блоки итераторов». То, что вы хотите сделать, это использовать ключевое слово yield, чтобы создать Enumerable вашего объекта Referal, что-то вроде этого (не то, чтобы я придумывал формат файла и имена свойств, потому что вы этого не делили):

public class Referral
{
    public Guid id { get; private set; } // "uniquify"
    public int ReferringId { get; set; }
    public string ReferrerText { get; set; }
    public string ReferrerDescription { get; set; }

    private Referral()
    {
       id = new Guid();
    }

    private Referral(string Text, string Description, int ReferringId) : this()
    {
        this.ReferrerText = Text;
        this.ReferrerDescription = Description;
        this.ReferringId = ReferringId;
    }

    public static IEnumerable<Referral> GetReferrals(string fileName) 
    {
        using (var rdr = new StreamReader(fileName))
        {
            var next = new Referrer();

            int state = 0;
            string line;
            while ( (line = rdr.ReadLine() ) != null)
            {
                switch (state)
                {
                    case 0:
                        next.ReferrerText = line;
                        state = 1;
                        break;

                    case 1:
                        next.ReferrerDescription = line;
                        state = 2;
                        break;

                    case 2:
                        next.ReferringId = int.Parse(line);
                        yield return next;
                        next = new Referral();
                        state = 0;
                        break;
                }
            }                
        }
    }
}

Теперь вы хотите для каких-то целей отсортировать рефералов и предположительно перечислить их. Вы можете легко это сделать так:

foreach (var referral in Referral.GetReferrals(@"C:\referralfile.txt").OrderBy( r => r.Text ) )
{
    OutputReferral(referral);
}
0 голосов
/ 21 июля 2009

Я не совсем понимаю, что вы пытаетесь сделать. Но, возможно, LINQ - это то, что вы ищете. Вокруг тонны документации, но в качестве быстрого «тизера» взгляните на образцы 101 Linq на MSDN

0 голосов
/ 21 июля 2009

Вы не можете игнорировать классы при использовании c #. Не сопротивляйся переменам!

Вам действительно не нужно создавать класс здесь? Вам действительно не нужно давать ему имя? C # позволяет свободно печатать, но безопасность типов - хорошая вещь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...