Reflection of an Object that is owned by another

Asked

Viewed 815 times

3

In my code I use a class called GenericField<T> which is used in all attributes of another class called Aplicacao. Until everything well, however, in another part of the code I need to get via Reflection the name of a class-specific attribute Aplicacao, which is actually an instance of GenericField<int>.

I tried the code below but did not get the expected answer (the attribute name that would be "id", instead I got "Gerericfield1"), the implementation of the two classes is soon after.

Aplicacao obj = new Aplicacao();
MessageBox.Show(obj.id.GetType().Name.ToString());

Class GenericField

[Serializable]
public class GenericField<T>
{
    private bool changeOldValue = true;

    private T _Value;
    public T Value
    {
        get { return _Value; }
        set
        {
            if (changeOldValue)
                _OldValue = value;

            _Value = value;
            changeOldValue = false;
        }
    }

    private T _OldValue;
    public T OldValue
    {
        get { return _OldValue; }
    }

    public override string ToString()
    {
        if (_Value == null)
            return "";
        return _Value.ToString();
    }
}

Class Aplicacao

public class Aplicacao : Objeto_DTL
{
    public Aplicacao()
    {
        _id = new GenericField<int>();
        _nome = new GenericField<string>();
        _descricao = new GenericField<string>();
        _criacao = new GenericField<DateTime>();
    }

    public override string ToString() { return _id.ToString() + " - " + _nome.ToString(); }

    private GenericField<int> _id;
    [DisplayName("ID")]
    public GenericField<int> id
    {
        get { return _id; }
        set { _id = value; }
    }

    private GenericField<string> _nome;
    [DisplayName("Nome")]
    public GenericField<string> nome
    {
        get { return _nome; }
        set { _nome = value; }
    }

    private GenericField<string> _descricao;
    [DisplayName("Descrição")]
    public GenericField<string> descricao
    {
        get { return _descricao; }
        set { _descricao = value; }
    }

    private GenericField<DateTime> _criacao;
    [DisplayName("Criação")]
    public GenericField<DateTime> criacao
    {
        get { return _criacao; }
        set { _criacao = value; }
    }
}
  • Here: MessageBox.Show(obj.id.GetType().Name.ToString()); you retrieve the name of the obj id property type name. This property has Genericfield type.

  • And how I get my name back?

  • 1

    Do you want the name of the property? It doesn’t make much sense. If you know what the property is, you know its name.

  • I want to create a function that will have as parameter a Genericfield and inside it I need to know the name of the attribute passed as parameter.

4 answers

2

Now I understand what you need. I think, the way you implement the classes, it’s not possible.

Check it out: the property (which you want to recover the name) is of the type GenericField. When a method receives this value, all it knows is about the variable (of type GenericField). No way to know where it is referenced (as class property Aplicacao, and maybe another place).

In your case this is reflected in your call obj.id. [etc.]. You use the name of the property. Of course, I imagine, your final code won’t be like this (the property will be passed on, and it won’t be called by itself obj.{propriedade}).

An example of what you are wanting: you have a class A with a member named id and a call quantidade, both int. You pass both to one method (say calcular(int a, int b), and wants to discover, within the method, the names of these members within the class A. Is not possible.

The solution here would be to include within GenericField a field string propertyName, and maybe a field object Parent.

  • Really I had already thought of a solution as the field string propertyName but I was looking for something more practical. Erei download the VS 2015 demo and test the nameof then decide which one to use because we are still in the design and prototyping phase. Once I have a definition put here.

1


  • Could you explain your answer better?

  • Sure, take a look at this link and see if it fits. http://www.c-sharpcorner.com/UploadFile/7ca517/the-new-feature-of-C-Sharp-6-0-nameof-operator/

  • 1

    That’s exactly it, I would like an issue in your reply putting the main points of the link, links are welcome, but insert in the answer the key points to answer the question in question.

  • It would solve my problem but unfortunately I still use Visual Studio 2013 and what I saw it does not support the reserved word nameof.

0

Hello, What you can also do is take the "Displayname" attribute from the property.

Ex :

Extension method:

public static T GetAttributeFrom<T>(this object instance, string propertyName) where T : Attribute
{
    var attrType = typeof(T);
    var property = instance.GetType().GetProperty(propertyName);
    return (T)property .GetCustomAttributes(attrType, false).First();
}

Code:

Aplicacao app = new Aplicacao();
var name = app.GetAttributeFrom<DisplayAttribute>("descricao").Name;

https://stackoverflow.com/questions/7027613/how-to-retrieve-data-annotations-from-code-programmatically

  • I already use "Displayname" to display the formatted name (with special characters) and I would have the same job to create an extra property in the class GenericField and fill it I really think I’ll wait for VS 2015 since I have time for it but en any case thanks.

-1

Please change the code to:

obj.Gettype(). Getproperty("id"). Name

--Edit

static void Main(string[] args)
    {
        Aplicacao obj = new Aplicacao();


        Console.WriteLine(GetName(() => obj.id));
    }

    public static string GetName<T>(Expression<Func<T>> e)
    {
        var member = (MemberExpression)e.Body;
        return member.Member.Name;
    }
  • I intend to create a function that will have as parameter a Genericfield and inside it I will need to know the name of the attribute passed as parameter so I can not use the way you described because I do not know which property will be passed.

  • Instead of including a new answer, edit the one you already included. You can do this by clicking on edit, just below the content of the reply.

  • I’ve edited, tested and works!

  • Solved? If yes could mark as answer?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.