Как Вы получаете имя переменной, поскольку оно было физически введено в его объявлении? [дубликат]

Ваша проблема не связана с VueJS / ThreeJs, вы должны просто исправить эту строку:

requestAnimationFrame( this.animate() );

Это должно быть:

requestAnimationFrame(this.animate)

Пожалуйста, прочитайте больше о обратном вызове: [112 ] https://developer.mozilla.org/en-US/docs/Glossary/Callback_function

34
задан Community 23 May 2017 в 10:30
поделиться

11 ответов

city в этом случае экземпляр типа string. Когда Вы звоните .GetType() Вы возвращаете фактический строковый тип, который не знает во всем Вашем конкретном городском экземпляре.

Мне нелегко видеть, почему Вы не можете только ввести "город" в коде как строковый литерал здесь, если это - то, в чем Вы нуждаетесь. Возможно, помогло бы, совместно использовали ли Вы то, для чего Вы хотите использовать это значение и при каких обстоятельствах Вы назовете Ваш DoSomething() функция.

В данный момент мое лучшее предположение - то, что то, что Вы действительно хотите сделать, является отражением все Person класс для получения списка полей в том классе:

public void DoSomething()
{
    MemberInfo[] members = this.GetType().GetMembers();

    // now you can do whatever you want with each of the members,
    // including checking their .Name properties.
}

Хорошо, на основе Вашего редактирования у меня есть еще немного для Вас.

Можно найти название полей, которые украшены атрибутом во времени выполнения как это:

Type t = typeof(Person);
foreach (MemberInfo member in t.GetMembers()
          .Where(m => 
                m.GetCustomAttributes(typeof(MyCustomAttribute)).Any()  ) )
{
    // "member" is a MemberInfo object for a Peson member that is 
    // decorated with your attribute
}

Можно также использовать обязательные флаги в первом GetMembers (), звонят для ограничения его просто полями, если Вы хотите.

7
ответ дан Joel Coehoorn 27 November 2019 в 16:07
поделиться

Вы упомянули, "т.е. Я должен получить строку "город" от экземпляра объектного города". Вы надеющийся получать имя поля от значения поля. Для example:If существует 2 Человека объектный с городом "Нью-Йорк" и другой с городом "Лондон", Вы ищущий функцию для возврата "города". Это то, под чем Вы подразумеваете динамичный?


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

 public enum ReflectionFields
{
    CITY = 0,
    STATE,
    ZIP,    
    COUNTRY

}

[AttributeUsage(AttributeTargets.Field,AllowMultiple=false)]
public class CustomFieldAttr : Attribute
{
    public ReflectionFields Field { get; private set; }
    public string MiscInfo { get; private set; }

    public CustomFieldAttr(ReflectionFields field, string miscInfo)
    {
        Field = field;
        MiscInfo = miscInfo;
    }
}

public class Person
{
    [CustomFieldAttr(ReflectionFields.CITY, "This is the primary city")]
    public string _city = "New York";

    public Person()
    {
    }
    public Person(string city)
    {
        _city = city;
    }

}

public static class AttributeReader<T> where T:class
{
    public static void Read(T t)
    {
        //get all fields which have the "CustomFieldAttribute applied to it"
        var fields = t.GetType().GetFields().Where(f => f.GetCustomAttributes(typeof(CustomFieldAttr), true).Length == 1);

        foreach (var field in fields)
        {
            var attr = field.GetCustomAttributes(typeof(CustomFieldAttr), true).First() as CustomFieldAttr;
            if (attr.Field == ReflectionFields.CITY)
            {
                //You have the field and you know its the City,do whatever processing you need.
                Console.WriteLine(field.Name);
            }
        }            
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        PPerson p1 = new PPerson("NewYork");
        PPerson p2 = new PPerson("London");
        AttributeReader<PPerson>.Read(p1);
        AttributeReader<PPerson>.Read(p2);

}
 }

Можно теперь свободно переименовать _city поле Человека к чему-то еще, и код вызова будет все еще работать, так как код с помощью отражения пытается определить поле с помощью набора перечисления значений ReflectionFields в качестве части инициализации набора атрибута на поле.

4
ответ дан Abhijeet Patel 27 November 2019 в 16:07
поделиться

Две вещи здесь.

Номер один, как кто-то выше указанного, Вы получаете Тип для строки, не для Человека. Так typeof (Человек).GetMembers () получит Вас список участников.

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

Ответ Abhijeet является более соответствующим, Вы отмечаете поле как городское поле, затем делаете то, что Вы любите с ним. То, где я не соглашаюсь, - то, что я использовал бы различные классы атрибута, а не перечисление.

Что-то как:

    public class MyAttribute : Attribute
    {

    }

    [AttributeUsage(AttributeTargets.Field)]
    public class MyCityAttribute : MyAttribute
    {
    }

    [AttributeUsage(AttributeTargets.Field]
    public class MyNameAttribute: MyAttribute
    {
    }

    public class Person
    {

        [MyCity]
        public string city = "New York";

        [MyCity]
        public string workCity = "Chicago";

        [MyName]
        public string fullName = "John Doe";

        public Person()
        {
        }


        public void DoSomething()
        {
            Type t = typeof(Person);
            FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public);

            foreach (var field in fields)
            {
                MyAttribute[] attributes = field.GetCustomAttributes(typeof(MyAttribute));
                if (attributes.Count > 0)
                {
                    if (attributes[0] is MyCityAttribute)
                    {
                        //Dosomething for city
                        break;
                    }

                    if (attributes[0] is MyNameAttribute)
                    {
                        //Dosomething for names
                        break;
                    }
                }
            }
        }
    }

Это позволило бы Вам использовать различные параметры для MyCity по сравнению с MyName, который будет иметь больше смысла в контексте обработки каждого.

Я думаю с Вашим комментарием 'гогота' выше, Вы попадаете в точку. То, что необходимо было бы изменить строковую константу, если Вы переименовываете свою переменную, является индикатором, что Вы делаете что-то не так.

1
ответ дан Darren Clark 27 November 2019 в 16:07
поделиться
t.GetField("city", BindingFlags.Public | BindingFlags.Instance);

или можно назвать GetFields () для получения всех полей

0
ответ дан Canton 27 November 2019 в 16:07
поделиться

Необходимо звонить, получают тип на классе Человек. Выполнение итерации полей класса как в ответе ниже

0
ответ дан Preet Sangha 27 November 2019 в 16:07
поделиться

Это не возможно (я думаю, что это на самом деле - всего лишь involes несколько взломов и лямбд использования). Если Вы хотите сохранить атрибуты о a Person и смогите получить название атрибута легко, я предлагаю использовать a Dictionary<TKey, TValue> от System.Collections.Generic пространство имен.

И можно всегда обнародовать свойства, которые переносят словарь.

public class Person
{
  Dictionary<string, string> attributes = new Dictionary<string, string();
  public string City
  {
    get { return attributes["city"]; }
    set { attributes["city"] = value; }
  }

  public Person()
  {
    City = "New York";
  }
}

И можно получить список всех атрибутов с attributes.Keys.

0
ответ дан Samuel 27 November 2019 в 16:07
поделиться

Взгляните на это сообщение, поскольку это выглядит подобным тому, что Вы пытаетесь сделать:

Нахождение имени переменной передало функции

(особенно ответ Konrad Rudolph), Другой подход мог быть, чтобы просто добавить "город" как один из параметров в атрибуте и извлечь это позже.

0
ответ дан Community 27 November 2019 в 16:07
поделиться

Вы уже - цикличное выполнение через набор FieldInfo объекты. Ищите свой атрибут на тех и когда Вы найдете FieldInfo это содержит Ваш атрибут, у Вас есть тот, который Вы хотите. Затем звоните .Name на нем.

system.reflection.fieldinfo.attributes

0
ответ дан brendanjerwin 27 November 2019 в 16:07
поделиться

Может вам это понадобится. Работает нормально.

Я нашел это здесь .

static void Main(string[] args)
{
    var domain = "matrix";
    Check(() => domain);
    Console.ReadLine();
}

static void Check<T>(Expression<Func<T>> expr)
{
    var body = ((MemberExpression)expr.Body);
    Console.WriteLine("Name is: {0}", body.Member.Name);
    Console.WriteLine("Value is: {0}", ((FieldInfo)body.Member)
   .GetValue(((ConstantExpression)body.Expression).Value));
}

Результат будет:

Name is: 'domain'
Value is: 'matrix'
50
ответ дан 27 November 2019 в 16:07
поделиться

Да, это возможно !!!

Попробуйте это ...

  public string DoSomething(object city)
  {
       return city.GetType().GetProperty("Name",typeof(string)).GetValue(city,null);
  }
4
ответ дан 27 November 2019 в 16:07
поделиться

Я знаю, что это старый вопрос, но я пытался добиться того же, и Google прислал меня сюда. Спустя много часов я наконец нашел способ. Я надеюсь, что кому-то это пригодится.

На самом деле есть больше способов добиться этого:

static void Main(string[] args) 
{
  GetName(new { var1 });
  GetName2(() => var1);
  GetName3(() => var1);
}

static string GetName<T>(T item) where T : class 
{
  return typeof(T).GetProperties()[0].Name;
}

static string GetName2<T>(Expression<Func<T>> expr) 
{
  return ((MemberExpression)expr.Body).Member.Name;
}

static string GetName3<T>(Func<T> expr) 
{
  return expr.Target.GetType().Module.ResolveField(BitConverter.ToInt32(expr.Method.GetMethodBody().GetILAsByteArray(), 2)).Name;
}

Первый - самый быстрый. Последние 2 примерно в 20 раз медленнее, чем 1-й.

http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html

37
ответ дан 27 November 2019 в 16:07
поделиться
Другие вопросы по тегам:

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