przypisanie listy generycznej do zmiennej aplikacyjnej

0

Cześć wam!

Niedawno zacząłem z pasją poznawać język programowania C# razem z technologią ASP.NET. Mam pewne zadanie w którym muszę przypisać utworzoną listę generyczną do zmiennej aplikacyjnej. Zrobiłem tak:

List<String> dane = new List<String>();

Application["wypowiedzi"] = dane;

to wyżej jest jako globalne.

W innej metodzie napisałem Application["wypowiedzi"] = dane.add("Testowe"); to kompilator nie przyjmuje tego.

Jak się przypisuje listę generyczną do zmiennej aplikacyjnej ?

0

Metoda List<T>.Add(...) nie zwraca niczego, więc jak chcesz to przypisać? Chcesz przypisać całą listę? Po prostu przypisz same dane.

0

Przypisałeś dobrze, to drugi fragment kodu jest bez sensu.
Spróbuj raczej tak:

(Application["wypowiedzi"] as List<string>).Add("Testowe");

A żeby nie powielać tego rzutowania wielokrotnie, zrób sobie właściwość typu List<string>.

0

To może nie rozumiem treści zadania:

To brzmi tak:

Na stronie Pisz.aspx użytkownik powinien mieć możliwość wprowadzenia swojej
wypowiedzi, która po naciśnięciu przycisku Pisz powinna zostać dopisana na pierwszej pozycji
listy przechowywanej w zmiennej aplikacyjnej Wypowiedzi. Treść wypowiedzi powinna zostać
poprzedzona wytłuszczonym identyfikatorem użytkownika. Po zapisaniu wypowiedzi pole
tekstowe powinno zostać wyczyszczone.

Jak to rozumiecie ?

0
somekind napisał(a)

Przypisałeś dobrze, to drugi fragment kodu jest bez sensu.
Spróbuj raczej tak:

(Application["wypowiedzi"] as List<string>).Add("Testowe");

A żeby nie powielać tego rzutowania wielokrotnie, zrób sobie właściwość typu List<string>.

Twój sposób mi nie działa. Przy dodawaniu danych wywala błąd taki:

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu.

Kurde musi być jakiś sposób żeby do tej zmiennej Application["wypowiedzi"] była przypisana lista generyczna. To jest to samo jak do zwykłej zmiennej tyle, że ta zmienna aplikacyjna to jest zmienna tablicowa asocjacyjna.

0

Skoro dostałeś NullRefereceException, to nie znaczy, że mój sposób jest zły. Prawdopodobnie wywołałeś ten kod w chwili, gdy jeszcze nie utworzyłeś swojej listy w zmiennej aplikacyjnej. Musisz sprawdzić czy Application["wypowiedzi"] nie jest null.

0

Nie powiedziałem, że Twój sposób jest zły. Po prostu jeszcze nie posiadam wiedzy jak użyć Twojego sposobu :)

Listę utworzyłem w metodzie Page Load:

protected void Page_Load(object sender, EventArgs e)
{
List<String> dane = new List<String>();

    }
0

A przypisales ja do Application["wypowiedzi"]? Bo w Twoim kodzie tego nie widac.

0

Może to pomoże.

Plik aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Pisz.aspx.cs" Inherits="WebApplication1.Pisz" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
        <br />
        <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
    </div>
    </form>
</body>
</html>

Plik cs:

 using System;
using System.Collections.Generic;

namespace WebApplication1
{
    public partial class Pisz : System.Web.UI.Page
    {
        // Naszą zmieną aplikacyjną opakowujemy we właściwość. Dzięki temu w jednym miejscu będziemy używali klucza, 
        // co zmniejsza ryzyko literówki, a ponadto zawsze będziemy mogli zmienić miejsce przechowywania danych 
        // z bezsensownie użytego tutaj Application na Session, ViewState albo jeszcze innego grzyba
        private List<string> Wypowiedzi
        {
            get 
            {
                // niczego nie zabezpieczamy, bo mamy pewność, że to zawsze zadziała
                return (List<string>)Application["wypowiedzi"]; 
            }
            set
            {
                Application["wypowiedzi"] = value;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                // prawie jak konstruktor - przy pierwszym załadowaniu strony tworzymy zmienną 
                this.Wypowiedzi = new List<string>();  
            }
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            this.Wypowiedzi.Add(this.TextBox1.Text);
            
            // dowód, że zapisywanie wypowiedzi działa
            this.Label1.Text = string.Empty;
            foreach (string s in this.Wypowiedzi)
            {
                this.Label1.Text += "<br/>" + s;
            }
        }
    }
}
0

zrobiłem w taki sposób:

Metody poniższe w pliku "pisz.aspx"

 
         protected void Page_Load(object sender, EventArgs e)
        {
            
            Application["wypowiedzi"] = new List<String>();

            if (Session["user"] != null)
            {
                Label1.Text = "Identyfikator użytkownika: <b>" + (String)Session["user"] + "<b/>";
            }
            else
            {
                Label1.Text = "Identyfikator użytkownika: <b>Anonim<b/>";
            }
           } 

        protected void Button1_Click(object sender, EventArgs e)
        {
            (Application["wypowiedzi"] as List<string>).Add("<b>" + Session["user"] + "</b>: " + TextBox1.Text);
            TextBox1.Text = "";

            
        }

A to w pliku "czytaj.aspx"

<%
        if (Application["Wypowiedzi"] != null)
        {
            Response.Write((Application["wypowiedzi"] as List<string>).Count);
            for (int i = 0; i < (Application["wypowiedzi"] as List<string>).Count; i++)
            {
                Response.Write((Application["wypowiedzi"] as List<string>)[i] + "<br/>");
                
            }
        }
    %> 

Jestem już blisko celu ale...
Jak dodam 2-3 elementów do listy czyli 2 i więcej wiadomości wyślę to tak naprawdę pierwszy element nadpisuje się. Nowe wartości nie są dodawane jako kolejne elementy listy tylko nadpisuje pierwszy element listy. Wiecie dlaczego to tak ?

0

Przy każdym załadowaniu strony tworzysz listę od nowa: Application["wypowiedzi"] = new List<String>();
Ja tego if (!this.IsPostBack) w swoim kodzie nie dałem dla picu, to jest ważne.

Nie uważasz, że wielokrotne wykonywanie tego samego kodu, jak np. (Application["wypowiedzi"] as List<string> w czytaj.aspx jest nieeleganckie?

0

Przy każdym załadowaniu strony tworzysz listę od nowa: Application["wypowiedzi"] = new List<String>();
Ja tego if (!this.IsPostBack) w swoim kodzie nie dałem dla picu, to jest ważne.

Masz rację, zapomniałem tego dodać.

Nie uważasz, że wielokrotne wykonywanie tego samego kodu, jak np. (Application["wypowiedzi"] as List<string> w czytaj.aspx jest nieeleganckie?

Nie wyczułem, żeby to było nieeleganckie. Musiałbym zobaczyć eleganckie sposoby.

Dodawanie do listy działa świetnie.
Jak wiecie, ta aplikacja to jest webchat. Tą aplikacje otworzyłem trzy razy w przeglądarce. Dla każdej wpisałem inny nick przed wejściem do czasu. Pierwszym nickiem pisałem coś na czacie i ładnie wyświetlało a drugim nickiem jak napisałem to wygląda na to jakby wiadomości z pierwszego nicka zostały nadpisane przez wiadomości drugiego nicka. Ja myślę, że to jest wina tego this.IsPostBack. Oświećcie mi.

A jednak działa tak jak chciałem!!!
Zrobiłem tak, ze zamiast this.IsPostBack dałem

 if (Application["wypowiedzi"] == null)
                Application["wypowiedzi"] = new List<String>(); 

Dzięki temu lista jest tworzona w momencie pierwszego użycia tej zmiennej przez kogolwiek aż do restartu serwera.

Dziękuję wam za przekazanie wiedzy dotyczącej list generycznych!

0
damian.u90 napisał(a)

Nie wyczułem, żeby to było nieeleganckie. Musiałbym zobaczyć eleganckie sposoby.

Wielokrotne stosowanie tego samego kawałka kodu jest zawsze nieeleganckie, jest to złamanie zasady DRY, a poza tym, przynajmniej w tym przypadku, obniża wydajność. Rzutowanie czy użycie operatora as kosztuje i nie ma sensu robienia tego wielokrotnie. Mógłbyś to zrobić raz, umieścić swoją listę stringów w jakiejś zmiennej lokalnej, a potem na niej operować - to by było eleganckie.
Poza tym nie ma sensu stosowanie as, jeśli wcześniej sprawdziłeś, że zmienna nie jest null, w tym wypadku wystarczy zwykłe rzutowanie.

Jak wiecie, ta aplikacja to jest webchat. Tą aplikacje otworzyłem trzy razy w przeglądarce. Dla każdej wpisałem inny nick przed wejściem do czasu. Pierwszym nickiem pisałem coś na czacie i ładnie wyświetlało a drugim nickiem jak napisałem to wygląda na to jakby wiadomości z pierwszego nicka zostały nadpisane przez wiadomości drugiego nicka. Ja myślę, że to jest wina tego this.IsPostBack.

Ja nie wiedziałem, że to czat, zakładałem, że jest jedna strona, na której dodajesz treść i wyświetlasz ją jednocześnie, dlatego podałem sposób z IsPostBack, który oczywiście nie miał prawa działać w przypadku wielokrotnie otwartej strony.

1 użytkowników online, w tym zalogowanych: 0, gości: 1