• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problemy z dostępnością danego elementu zmiennej

VPS Starter Arubacloud
0 głosów
397 wizyt
pytanie zadane 22 grudnia 2021 w C# przez Code_ Użytkownik (520 p.)

Podczas programowania programu, który generuje tekst typu "znajdź n wśród m" wyskoczył błąd z dostępnością zmiennej. Oto jego zawartość: (CS0200) Nie można przypisać wartości do właściwości lub indeksatora "string.this[int]" - jest on tylko do odczytu. Przesyłam również zawartość kodu:

using System;

namespace founding
{
    class Program
    {
        
        static void Main(string[] args)
        {
            Random r = new Random();
            int los = r.Next(1,10001);
            

            Class1 c = new Class1();
            
            int liczba = 0;
            for (int i = 1; i <= 10000; i++)
            {
                if (i == los)
                {
                    c.string_chain[i] = 'L';
                }
                else
                {
                    c.string_chain[i] = "I"; 
                }
                liczba++;

                
            }
            Console.WriteLine(c.string_chain);
            Console.WriteLine(liczba);
            Console.WriteLine(los);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace founding
{
    class Class1
    {
        public string  string_chain { get; set; } = " ";
        


    }
}

Błąd wyskakuje w 21 oraz 25 linijce w pliku Program.cs

Macie jakieś pomysły jak można zniwelować ten błąd? Z góry dziękuję.

2 odpowiedzi

0 głosów
odpowiedź 22 grudnia 2021 przez Wiciorny Ekspert (269,120 p.)

Nie wiem jak do końca jest w C# ale zapis odnosi się do pozycji jak w tablicy, a nie wywołania funkcji 

 c.string_chain[i]

c- to obiekt klasy, natomiast string_chain to  jest element klasy jako pole a nie jako tablica, więc nie możesz odwołać się jakby do indeksu z użyciem [i] 
 

class Osoba
{
    public int Wiek { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Osoba Karol = new Osoba();
        
        Karol.Wiek = 21;
        System.Console.WriteLine(Karol.Wiek);
        
        System.Console.ReadKey();
    }
}

w tej sytuacji jedynie jak możesz to zapisać to 

if (i == los)
                {
                    c.string_chain = 'L';
                }
                else
                {
                    c.string_chain = "I"; 
                }

 

komentarz 22 grudnia 2021 przez DarthMazut Bywalec (2,990 p.)

c- to obiekt klasy, natomiast string_chain to  jest element klasy jako pole a nie jako tablica, więc nie możesz odwołać się jakby do indeksu z użyciem [i]

Ad 1. string_chain jest zdefiniowany jako property, a nie pole, proszę zwrócić uwagę, że posiada getter oraz setter

Ad 2. Jak najbardziej można odwoływać się do poszczególnych znaków stringa, za pomocą tzn. indexerów ( np. char x = myString[2]), natomiast tak jak wspomniałem w mojej odpowiedzi nie można w ten sposób stringa modyfikować

komentarz 22 grudnia 2021 przez Wiciorny Ekspert (269,120 p.)

można modyfikować string, bo modyfikujesz refrencje i na to Ci odpowiedziałem nawet pokazałem Ci program który to robi. 

Properties służy do odwołania 

 Do zmiennych private  można uzyskać dostęp tylko w obrębie tej samej klasy (klasa zewnętrzna nie ma do niej dostępu). Czasami jednak potrzebujemy do nich dostępu - i można to zrobić za pomocą properites

Właściwość jest jak połączenie zmiennej i metody i ma dwie metody: a get i set metodę:

 co do modyfikowania jak do tablicy, to fakt to kwestia stringa okej napisałem to wyraźnie że nie jestem pewny na co pozwala tu c# :) ale w kwestii mutowalności musisz nadrobić sporo, bo to co przekazałeś jest totalnym błędem 

komentarz 23 grudnia 2021 przez DarthMazut Bywalec (2,990 p.)

Ok, czyli oficjalna dokumentacja Microsoftu (https://docs.microsoft.com/en-us/dotnet/api/system.string?view=net-6.0) też się myli tak?

A String object is called immutable (read-only), because its value cannot be modified after it has been created. Methods that appear to modify a String object actually return a new String object that contains the modification.

Because strings are immutable, string manipulation routines that perform repeated additions or deletions to what appears to be a single string can exact a significant performance penalty...

Jeśli wg. Ciebie niemutowalność polega na niemożliwości zmiany obiektu na który wskazuje referencja tzn. że definicja obiektu niemutowalnego, również jest źle podana na wiki:

https://en.wikipedia.org/wiki/Immutable_object

In object-oriented and functional programming, an immutable object (unchangeable[1] object) is an object whose state cannot be modified after it is created.

tak?

Czyli wg. Ciebie immutable jest tożsame z readonly?

0 głosów
odpowiedź 22 grudnia 2021 przez DarthMazut Bywalec (2,990 p.)

Cześć smiley

ze względów bezpieczeństwa stringi w C# są immutable. "Modyfikację" istniejącego stringa, można przeprowadzić wyłącznie przez podmianę danego łańcucha znaków nowym obiektem. Wyrażenie:

c.string_chain[i] = 'L';

próbuje w oczywisty sposób modyfikować dany string, więc kompilator na to nie pozwoli.

Jeżeli chcesz w ten sposób pracować na stringach użyj klasy StringBuilder, np.:

StringBuilder sb = new("Hello there!");
sb[6] = 'T';
string myOutputString = sb.ToString();

Inna sprawa to, to, że w Twoim przypadku string_chain jest inicializowany tylko 1 znakiem białym. Jeśli tak, to nie możesz się odwoływać do indexów większych niż (string_chain.Length - 1), bo dostaniesz IndexOutOfRangeException.

Nie wiem do końca jaki był Twój zamysł, ale jeśli chcesz tworzyć string po 1 znaku to użyj konkatenacji (operator +=) lub jeśli zależy Ci na wydajności to klasy StringBuilder.

Pozdrawaim

komentarz 22 grudnia 2021 przez Wiciorny Ekspert (269,120 p.)
edycja 22 grudnia 2021 przez Wiciorny

ze względów bezpieczeństwa stringi w C# są immutable. "Modyfikację" istniejącego stringa, można przeprowadzić wyłącznie przez podmianę danego łańcucha znaków nowym obiektem. Wyrażenie:

 

c.string_chain[i] = 'L';

próbuje w oczywisty sposób modyfikować dany string, więc kompilator na to nie pozwoli.

To nie jest prawda gdyż,  tutaj nie modyfikuje istniejącego stringa (perse),tylko ta modyfikacja polega na tym, że kolega  tworzy nową referencje ... :) do nowego obiektu i ta operacja jest dozwolona jeśli nie byłaby to tablica jak kolega źle napisal 


c.string_chain = 'L'; // jest poprawne po prostu tworzona jest nowa referencja 

Niezmienność oznacza że nie możesz modyfikować obiektu "Samego-sobie", ale możesz zmienić refrenecje do tego obiektu 

 

tu masz prosty test, dodatkowo to nawet nie jest element klasy

using System;
					
public class Program
{
	public static void Main()
	{
		Console.WriteLine("Hello World");
		int b=0;
		string ix= "String before";
		ix = "new String";
		Console.WriteLine(ix);
	}
}

 

komentarz 22 grudnia 2021 przez Wiciorny Ekspert (269,120 p.)
od razu dodaje - > analizując podanie przykładu modyfikacji jednego z elementów stringa [index] masz racje... :) ale w zakresie całkowitej niemutowalności się nie zgadza
komentarz 23 grudnia 2021 przez DarthMazut Bywalec (2,990 p.)
c.string_chain = 'L'; // jest poprawne po prostu tworzona jest nowa referencja

Nie jest poprawne. "Cannot implicitly convert type char to string".

Nawet jeśli zamienić przypisanie na "L" to również nie jest tworzona, żadna nowa referencja tylko c.string_chain będzie wskazywać na nowy string utworzony na stercie.

To, że wskaźnik może być przestawiony z niemutowalnego obiektu na inny nie umniejsza w żadnym stopniu niemutowalności tego pierwszego. Z resztą sam napisałeś czym jest niemutowalność i nawet to zdanie było poprawne:

Niezmienność oznacza że nie możesz modyfikować obiektu "Samego-sobie", ale możesz zmienić refrenecje do tego obiektu

Co ciekawe, w następnym komentarzu już piszesz, że skoro można sobie przestawić wskaźnik, który wskazuje na obiekt niemutowalny to wtedy ten obiekt nie jest "całkowicie niemutowalny" ? To może jeszcze są jakieś obiekty pół-mutowalne? xD

Ciężko mi zrozumieć Twoje podejście, przeczysz sam sobie, wprowadzasz w błąd, nawet dajesz jakąś randomową wstawkę na temat properties - jakby miało to usprawiedliwić, że property nazwałeś polem...

Chyba szkoda jednak mojego czasu tutaj... szkól dalej młodych adeptów że stringi nie są niemutowalne, bo Ty tak mówisz, a wszyscy inni, wraz z dokumentacją się mylą

Podobne pytania

0 głosów
4 odpowiedzi 324 wizyt
+1 głos
2 odpowiedzi 1,202 wizyt
0 głosów
3 odpowiedzi 265 wizyt
pytanie zadane 27 października 2022 w C# przez JoannS Początkujący (250 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...