Zmienne - zmiana według ich nazw

0

Bawiłem się trochę js-em i interesuje mnie czy w C# istnieje coś podobnego do window oraz eval
W JavaScript wyglądało to tak
window

// Nasza zmienna
var a2 = 5;

// Zmieniamy wartość
window["a"+2] = 40;

// Wyprowadzamy zmienną a2, która ma teraz wartość 40
alert(a2);

eval

// Nasza zmienna
var a2 = 5;

// Zmieniamy wartość
a2 = 2*eval("a" + 2);

// Wyprowadzamy zmienną a2, która ma teraz wartość 10
alert(a2);

Chciałbym wytłumaczyć inaczej, jednak nie potrafię :/

Mój problem w c# wygląda tak że mam listę w klasie. Ale chcę w niej trzymać tak jak by nazwy zmiennych z innej klasy i móc je zmienić w trakcie wykonywania pętli foreach.

2

W tym celu można użyć Dictionary.

var window = new Dictionary<string, int>();
window["a2"] = 5;
window["a" + 2] = 40;
Console.WriteLine(window["a2"]); // wyświetli 40

Ale lepiej opisz co dokładnie chcesz uzyskać, bo może coś przekombinowujesz.
Co do evala, nie da się tego łatwo uzyskać, można generować kod w locie, ale w 99,99% nie jest to potrzebne, albo używa się bibliotek które robią to pod spodem.

0
mad_penguin napisał(a):

W tym celu można użyć Dictionary.

var window = new Dictionary<string, int>();
window["a2"] = 5;
window["a" + 2] = 40;
Console.WriteLine(window["a2"]); // wyświetli 40

Ale lepiej opisz co dokładnie chcesz uzyskać, bo może coś przekombinowujesz.
Co do evala, nie da się tego łatwo uzyskać, można generować kod w locie, ale w 99,99% nie jest to potrzebne, albo używa się bibliotek które robią to pod spodem.

teraz sam zastanawiam się czy dobrze myślę...
Przykładowo

class Samochod {
    class Program
    {
        public static int liczba = 5;
        static void Main(string[] args)
        {
            Japonia.zmien();
            Console.WriteLine(liczba);
 
           Console.ReadLine();
        }
    }

    static class Japonia
    {
        public static void zmien()
        { 
            Program.liczba = 40;
        }
    }

w klasie Japonia jest funkcja zmien() i w niej zmieniam zmienną za pomocą:
Program.liczba = 40;
czy mogę te Program.liczba zapisać jakoś?
żeby na przykład było:
japonia = Program.liczba;
i potem to wywoła ten sam efekt:
japonia = 40; będzie miało taki sam efekt jak Program.liczba = 40;

Tylko nie wiem czego użyć, aby to zrobić. (Mam nadzieję że napisałem zrozumiale)

0

takie coś?

Dictionary<string, int> kraje = new Dictionary<string, int>();

kraje.Add("Japonia", 150);

Console.WriteLine(kraje["Japonia"]); // 150

kraje["Japonia"] = 120;

Console.WriteLine(kraje["Japonia"]); // 120

lub

public class Country
{
    public string name;
    public int someValue;

    public Country(string name)
    {
        this.name = name;
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        Country country = new Country("Japonia");
        country.someValue = 150;
    }
}
5
..V.. napisał(a):

Bawiłem się trochę js-em i interesuje mnie czy w C# istnieje coś podobnego do window

Nie, C# to nie jest język interpretowany przez przeglądarkę, więc nie ma sensu, aby istniał w nim jakiś globalny obiekt okna przeglądarki.

oraz eval

C# to język kompilowany, więc nie można tak po prostu wywołać interpretacji danego stringa jako kodu źródłowego. Ale można skompilować kod dynamicznie w locie i go wywołać, np. tak jak tutaj

W JavaScript wyglądało to tak
window

// Zmieniamy wartość
window["a"+2] = 40;

Tego też nie zrobisz, bo C# jest statycznie typowany i nie można sobie tak po prostu rozszerzać obiektów o nowe właściwości w locie. Tzn. jest nawet dostępny typ dynamic, który zachowuje się jak typy dynamiczne w innych językach (można go np. rozszerzać), ale i tak jest statycznie typowany.

Mój problem w c# wygląda tak że mam listę w klasie. Ale chcę w niej trzymać tak jak by nazwy zmiennych z innej klasy i móc je zmienić w trakcie wykonywania pętli foreach.

Ale czemu chcesz tak robić? Bo tak się robiło w JS?

A czemu nie mieć np. kolekcji wyrażeń przypisujących właściwości, np. tak:

var properties = new Action<Person, string>[] { (p, v) => p.FirstName = v, (p, v) => p.LastName = v };
var person = new Person();
foreach (var prop in properties)
{
    prop.Invoke(person, "abc");
}
Console.WriteLine($"{person.FirstName} {person.LastName}");

Można też zamiast mieć kolekcję właściwości zamiast kolekcji przypisań, tylko wtedy trzeba przypisania dokonać "ręcznie" za pomocą refleksji:

var propertyExpressions = new Expression<Func<Person, string>>[] { p => p.FirstName, p => p.LastName };
foreach (var expr in propertyExpressions)
{
    var memberExpression = (MemberExpression)expr.Body;
    var property = (PropertyInfo)memberExpression.Member;
    var setMethod = property.GetSetMethod();
    setMethod.Invoke(person, new[] { "ghi" });
}
Console.WriteLine($"{person.FirstName} {person.LastName}");

Ogólnie można cudować na różne sposoby, tylko niekoniecznie jest sens. Napisz, jaki masz faktyczny problem, bo to, że coś się rozwiązuje w jakiś sposób w jednym języku nie znaczy, że we wszystkich innych będzie tak samo.

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