Что такое лучший, более чистый способ использовать Список <T>

Я надеюсь реализовывать несколько более хороших способов использовать Список в нескольких приложениях, я продолжаю работать. Моя текущая реализация похожа на это.

MyPage.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
    BLL.PostCollection oPost = new BLL.PostCollection();
    oPost.OpenRecent();
    rptPosts.DataSource = oArt;
    rptPosts.DataBind();
}

Класс (классы) BLL

public class Post
{
    public int PostId { get; set; }
    public string PostTitle { get; set; }
    public string PostContent { get; set; }
    public string PostCreatedDate { get; set; }

    public void OpenRecentInitFromRow(DataRow row)
    {
        this.PostId = (int) row["id"];
        this.PostTitle = (string) row["title"];
        this.PostContent = (string) row["content"];
        this.PostCreatedDate = (DateTime) row["createddate"];
    }
}
public class PostCollection : List<Post>
{
    public void OpenRecent()
    {
        DataSet ds = DbProvider.Instance().Post_ListRecent();
        foreach (DataRow row in ds.Tables[0].Rows)
        {
            Post oPost = new Post();
            oPost.OpenRecentInitFromRow(row);
            Add(oPost);
        }
    }
}

Теперь, в то время как это работает все хорошо и хорошее, я просто задаюсь вопросом, существует ли какой-либо способ улучшить его и просто сделать его инструментом для очистки, который, имея необходимость использовать два различных класса делают к чему-то, что я думаю, может произойти во всего одном классе или использовании интерфейса.

9
задан Tim Meers 25 May 2010 в 13:27
поделиться

5 ответов

Во-первых, я бы не стал выводить List - вы на самом деле не специализируете поведение.

Я также предлагаю сделать Post неизменяемым (по крайней мере, внешне) и написать статический метод (или конструктор) для его создания на основе DataRow:

public static Post FromDataRow(DataRow row)

Точно так же вы можете иметь метод списка:

public static List<Post> RecentPosts()

, который их возвращает. По общему признанию, это могло бы быть лучше в качестве метода экземпляра в каком-то классе DAL, который позволит издеваться и т. Д. В качестве альтернативы, в Post:

public static List<Post> ListFromDataSet(DataSet ds)

Теперь, что касается использования List Сам - вы используете .NET 3.5? Если это так, вы можете сделать это значительно более аккуратно, используя LINQ:

public static List<Post> ListFromDataSet(DataSet ds)
{
    return ds.Tables[0].AsEnumerable()
                       .Select(row => Post.FromDataRow(row))
                       .ToList();
}
17
ответ дан 4 December 2019 в 09:12
поделиться

Изменить: ответ Джона Скита, вероятно, лучший вариант. Но если вы хотите внести всего несколько простых изменений, читайте дальше:

Поместите код доступа к базе данных OpenRecentInitFromRow в PostCollection и рассматривайте его как класс менеджера сообщений. Таким образом, класс Post представляет собой простой старый объект передачи данных.

public class Post
{
    public int PostId { get; set; }
    public string PostTitle { get; set; }
    public string PostContent { get; set; }
    public string PostCreatedDate { get; set; }
}

public class PostCollection : List<Post>
{
    public void OpenRecent()
    {
        DataSet ds = DbProvider.Instance().Post_ListRecent();
        foreach (DataRow row in ds.Tables[0].Rows)
        {
            Add(LoadPostFromRow(row));
        }
    }

    private Post LoadPostFromRow(DataRow row)
    {
        Post post = new Post();
        post.PostId = (int) row["id"];
        post.PostTitle = (string) row["title"];
        post.PostContent = (string) row["content"];
        post.PostCreatedDate = (DateTime) row["createddate"];
        return post;
    }
}
2
ответ дан 4 December 2019 в 09:12
поделиться

Вы можете сделать это:

protected void Page_Load(object sender, EventArgs e)
{
    BLL.PostCollection oPost = new BLL.PostCollection();
    rptPosts.DataSource = Post.OpenRecent();
    rptPosts.DataBind();
}
public class Post
{
    public int PostId { get; set; }
    public string PostTitle { get; set; }
    public string PostContent { get; set; }
    public string PostCreatedDate { get; set; }

    public void OpenRecentInitFromRow(DataRow row)
    {
        this.PostId = (int) row["id"];
        this.PostTitle = (string) row["title"];
        this.PostContent = (string) row["content"];
        this.PostCreatedDate = (DateTime) row["createddate"];
    }

    public static List<Post> OpenRecent()
    {
        DataSet ds = DbProvider.Instance().Post_ListRecent();
        foreach (DataRow row in ds.Tables[0].Rows)
        {
            Post oPost = new Post();
            oPost.OpenRecentInitFromRow(row);
            Add(oPost); //Not sure what this is doing
        }
        //need to return a List<Post>
    }
}
0
ответ дан 4 December 2019 в 09:12
поделиться

Я ищу несколько более удобных способов использования List

Это кажется странным запросом. Тип «Список» - это средство, а не цель.Имея это в виду, один из лучших способов достичь вашей реальной цели - использовать IEnumerable, а не List, потому что этот List заставляет вас хранить всю вашу коллекцию в памяти, в то время как IEnumerable требует только одного объекта за раз. Хитрость заключается в том, что вам нужно подключить все в потоке обработки, от уровня данных до представления, чтобы использовать его.

В приведенной ниже ссылке у меня есть хороший пример того, как сделать это очень чистым способом:
Самый быстрый метод для SQL Server вставляет, обновляет, выбирает

В зависимости от вашего существующего кода уровня данных вы можете чтобы просмотреть большую часть первой половины (длинного) сообщения - главное, что вы используете блок итератора, чтобы превратить SqlDataReader в IEnumerable . Как только вы это сделаете, все остальное будет довольно просто.

2
ответ дан 4 December 2019 в 09:12
поделиться

Вы используете List , потому что хотите предложить другим потребителям PostCollection возможность добавлять и удалять элементы? Я предполагаю, что нет, и что на самом деле вам просто нужен способ предоставить коллекцию, к которой вы можете привязаться. Если это так, вы могли бы рассмотреть итератор, возможно:

class BLL {
    ...

    public IEnumerable<Post> RecentPosts {
        get {
            DataSet ds = DbProvider.Instance().Post_ListRecent(); 
            foreach (DataRow row in ds.Tables[0].Rows) 
            { 
                Post oPost = new Post(); 
                oPost.OpenRecentInitFromRow(row); 
                yield return oPost;
            } 
        }
    }    

    ...
}

Несмотря на то, что это может считаться плохой формой (в том смысле, что у нас есть средство получения свойства, которое может выполнять сетевой вызов), этот подход итератора устранит накладные расходы вызова OpenRecentInitFromRow для сообщений, которые никогда не перечисляются.

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

2
ответ дан 4 December 2019 в 09:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: