Click here to Skip to main content
15,908,843 members
Please Sign up or sign in to vote.
4.50/5 (2 votes)
See more:
Hello experts,

since an earlier[^] question didn't receive any answers, I'm trying a more general approach:

I know that I can store whatever I want within an attribute at design time. I can also read the information at runtime.

Is ist generally possible to change the stored information at runtime?

Ciao,


luker

Edit:
I don't know another, more precise name for the mentioned attribute. With a look at this sample code, you will know which sort of attributes I'm talking about:
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public class FooAttribute : System.Attribute
{
    private bool _foo = false;

    public bool Foo
    {
        get { return (_foo); }
        set { _foo = value; }
    }

    public FooAttribute(bool value)
    {
        _foo = value;
    }

    public static void SetValue(object container, string property, bool value)
    {
        System.Reflection.PropertyInfo[] piAll = container.GetType().GetProperties();
        foreach (System.Reflection.PropertyInfo pi in piAll)
        {
            if (pi.Name != property)
                continue;

            FooAttribute[] fooAttributes = (FooAttribute[])(pi.GetCustomAttributes(typeof(FooAttribute), false));
            if (fooAttributes.Length <= 0)
                continue;

            fooAttributes[0].Foo = value;
            return;
        }
        throw new Exception("Property \"" + property + "\" in object \"" + container.ToString() + "\" is not decorated with FooAttribute.");
    }
And just for clarification, this is not about applying and removing attributes at run time. It's about changing the data stored within the attribute at run time.
Posted
Updated 16-Mar-11 23:13pm
v2

First, to answer your Question literally:
Is it generally possible to change the stored information at runtime?
No, this is not possible and makes no sense. You should understand the difference between data and meta-data. For example, you have a class. It's instance (and static members) work with some data you generally can change during run-time. An example if meta-data is the name of the class. You can retrieve the name of the class or any member using reflection. Can you change the name of the class or any member? Does it make any sense? I don't think so. Same thing about the data of the Attribute; it curves the same purpose as class or member name: meta-data. This is the same stuff: you retrieve this meta-data using reflection. But to change? No. Attribute adds meta-data to an assembly, a type, a member but it does not characterize and instance; this is the key.

This is about PropertyGrid, as I understand your original Question. (You should have clarify that in your present Question.)

I have a detailed work plan for the custom use of PropertyGrid in reply to this Question: How to get response when click PropertyGrid[^].

Please take a look and ask more clear follow-up Question if it seems to be relevant (or even not quite relevant). You really need to explain your idea in more detail.

—SA
 
Share this answer
 
v2
Comments
Albin Abel 18-Mar-11 0:35am    
Good one. my 5
Sergey Alexandrovich Kryukov 18-Mar-11 0:40am    
Thank you, Albin.
--SA
An attribute is an object attached to the Type of an object - you can change it's values at runtime. The effect would be similar to declaring a static value in the class itself. Probably why this isn't a something you'll see all that often. - hmm, that wasn't exactly correct, sorry ...

Seems something like this is required:
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Harlinn.CP.AttributeTest
{
    [AttributeUsage(AttributeTargets.All)]
    public class MyAttribute : Attribute
    {
        private static Dictionary<string, string> values = new Dictionary<string, string>();
        private string key;
        public MyAttribute(string key,string text)
        {
            this.key = key;
            if (values.ContainsKey(key) == false)
            {
                values[key] = text;
            }
        }
        public string Text
        {
            get { return values.ContainsKey(key)? values[key]:string.Empty; }
            set { if (Text == value) { return; } values[key] = value; } 
        }
    }
    class Program
    {
        
        static void Main(string[] args)
        {
            MyMethod("Test1");
            MyMethod("Test2");
        }
        [My("MyMethod", "Initial")]
        private static void MyMethod(string text)
        {
            MethodBase method = MethodBase.GetCurrentMethod();
            object[] attributes = method.GetCustomAttributes(typeof(MyAttribute),false);
            MyAttribute myAttribute = attributes[0] as MyAttribute;
            if (myAttribute != null)
            {
                Console.Out.WriteLine(myAttribute.Text);
                myAttribute.Text = text;
                Console.Out.WriteLine(myAttribute.Text);
            }
        }
    }
}


To get rid of the key in the destructor, you'll probably to do an initial analysis of where it's applied - possibly using Type.Fullname + member as key, looking it up seems to require a similar effort, so maybe passing the key is a reasonable solution.

outputs:
Initial
Test1
Test1
Test2

Best regards
Espen Harlinn
 
Share this answer
 
v2
Comments
Albin Abel 18-Mar-11 0:35am    
Nice effort, my 5
Espen Harlinn 18-Mar-11 4:50am    
Thank you, AlbinAbel!
Abhinav S 18-Mar-11 8:04am    
Good answer.5.
Sergey Alexandrovich Kryukov 18-Mar-11 14:47pm    
Espen, I don't see how this answers to the question "Is it generally possible to change the stored information at runtime?" The answer should be "no". After I looked at your answer, I updated mine to answer why.
--SA
Espen Harlinn 24-Mar-11 16:51pm    
I'm not entirely sure, at least not until I've investigated this a bit further. If I could figure it it out, I actually have some use for adding and editing attributes at runtime - but as far as I can tell it will probably have to involve some bytecode manipulation, possibly using cecil or something similar - and in the end it might be more trouble than it's actually worth - at least for now :)
Hey there!

It's not abvious what kind of attribute you mean here. As I read the earlier question I understand you mean the assembly attributes. I so, there's no way in my opinion) to change those attributes at runtime without having to compile your project.

Good luck,

Eduard
 
Share this answer
 
Comments
lukeer 17-Mar-11 5:19am    
For the attribute kind, I updated my question.
If it's really impossible todo, beside it was annoying, what would be the reason my SetValue() method would seem to work (no errors o nor exceptions) while having no effect on the targeted attribute's value, which is unchanged the next time I read it?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900