Страница 1 из 1

И снова рефлексия :) (Доступ к полю через строку)

СообщениеДобавлено: 01 дек 2018, 01:24
1max1
Синтаксис:
Используется csharp
// Есть 2 класса, один обычный, другой статический:
class Class1
{
    public int value;
}

static class Class2
{
    public static Class1 c1 = new Class1();
}

// Хочу сделать метод который будет возвращать значение переменной Class2.c1.value, выглядит сигнатура примерно так:
public static object GetVariableValueOfStaticClass(string variablePath) { }
// Или так:
public static T GetVariableValueOfStaticClass<T>(string variablePath) { }

// Применяется так:
int value = (int)GetVariableValueOfStaticClass("Class2.c1.value");

// Осталось только написать тело метода)
 

Re: И снова рефлексия :) (Доступ к полю через строку)

СообщениеДобавлено: 01 дек 2018, 05:20
Anonymyx
Вы в данном случае возвращаете переменную не статик класса.
Синтаксис:
Используется csharp
 int value = (int) typeof(Class1).GetField("value").GetValue(Class2.c1);

Статик класс всего лишь хранит экземпляр обычного класса, из которого и достается переменная.
Если переменная достается из static класса, то в метод GetValue() просто передается null.
Так что ваш метод должен иметь еще 2 аргумента типа Type и object:
Синтаксис:
Используется csharp
 
  public static T GetVariableValue<T>(string name, Type type, object obj)  => (T)type.GetField(name).GetValue(obj);
...
  int value = GetVariableValue<int>("value", typeof(Class1), Class2.cl1);
  int value = GetVariableValue<int>("value", typeof(Class2), null); //достаем публичную статическую переменную типа int из Class2.


 


А смысл данного метода в общем, если все это делается и так за 1 строчку - не совсем ясен.

Re: И снова рефлексия :) (Доступ к полю через строку)

СообщениеДобавлено: 01 дек 2018, 14:00
1max1
Эта костылизация мне нужна для того чтобы получать доступ к полю через строку, напрямую из кода обратится нельзя, и вот почему - у меня есть скрипт, который создает всплывающие подсказки (Обычный Image + Text), в нем есть поле с текстом и в это поле я хотел бы передавать параметры.

Синтаксис:
Используется csharp
static class Player
{
    public static float money;
}
 


Re: И снова рефлексия :) (Доступ к полю через строку)

СообщениеДобавлено: 01 дек 2018, 18:20
Anonymyx
Сделать свой класс для астероида с описанием и с методом GetDescryption() который возвращает это описание, если нужно вставляя значения переменных. При наведении передавать возвращаемую этим методом строку в универсальный класс Tooltip.Show(). Использовать рефлексию для подобных задач все ровно что забивать гвоздь трехтонной кувалдой.

Re: И снова рефлексия :) (Доступ к полю через строку)

СообщениеДобавлено: 01 дек 2018, 19:35
1max1
Сделать свой класс для астероида с описанием и с методом GetDescryption() который возвращает это описание, если нужно вставляя значения переменных.

Можно конечно, но хотелось бы всё сделать универсально и независимо. Рефлексия штука тяжелая, не спорю, но мне ее всего 1 раз в пятилетку юзануть нужно.

Re: И снова рефлексия :) (Доступ к полю через строку)

СообщениеДобавлено: 01 дек 2018, 22:26
Tolking
Именно для этого созданы интерфейсы...

Re: И снова рефлексия :) (Доступ к полю через строку)

СообщениеДобавлено: 02 дек 2018, 01:02
lawson
Tolking писал(а):Именно для этого созданы интерфейсы...

да хспади зачем эти интерфейсы!? Anonymyx правильный вариант подсказал - общий метод, который для каждого объекта вернет необходимые свойства.
Скрытый текст:
Только Descryption пишется Description

Re: И снова рефлексия :) (Доступ к полю через строку)

СообщениеДобавлено: 02 дек 2018, 12:53
Tolking
Интерфейс нужен чтобы не перебирать все возможные виды компонент у которых есть описание, а сразу получить интерфейс и получить описание...

Re: И снова рефлексия :) (Доступ к полю через строку)

СообщениеДобавлено: 09 дек 2018, 02:12
Ziza
Как-то так
Синтаксис:
Используется csharp
public static object GetVariableValueOfStaticClass(string variablePath)
{
    if (String.IsNullOrEmpty(variablePath))
        return null;
   
    var parts = variablePath.Split('.');
    var lenght = parts.Length;
   
    var type = Type.GetType(parts[0]);
    if (type == null || lenght == 1)
        return null;
   
    object value = null;
    BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
        | BindingFlags.Static;
   
    for (var i = 1; i < lenght; ++i)
    {
        var info = type.GetField(parts[i], flags);
       
        if (info == null)
            break;
       
        value = info.GetValue(value);
        type = value.GetType();
    }

    return value;
}

Re: И снова рефлексия :) (Доступ к полю через строку)

СообщениеДобавлено: 09 дек 2018, 10:23
1max1
Спасибо, примерно так я и решил, только у тебя попроще будет)

Re: И снова рефлексия :) (Доступ к полю через строку)

СообщениеДобавлено: 09 дек 2018, 16:03
Anonymyx
Синтаксис:
Используется csharp
("Class2.c1.value");

Ой....я неправильно понял вопрос.