Pergunta

É possível adicionar atributos em tempo de execução ou para alterar o valor de um atributo em tempo de execução?

Foi útil?

Solução

Os atributos são metadados estático. Montagens, módulos, tipos, membros, parâmetros e valores de retorno são não de primeira classe objetos em C # (por exemplo, a classe System.Type é meramente uma representação refletida de um tipo). Você pode obter uma instância de um atributo para um tipo e alterar as propriedades se eles estão gravável mas isso não afetará o atributo como ele é aplicado ao tipo.

Outras dicas

Isso realmente depende do que exatamente você está tentando realizar.

O System.ComponentModel.TypeDescriptor material pode ser usado para adicionar atributos para tipos, propriedades e instâncias de objetos, e tem a limitação que você tem que usá-lo para recuperar essas propriedades também. Se você estiver escrevendo o código que consome esses atributos, e você pode viver dentro dessas limitações, então eu definitivamente sugerir isso.

Tanto quanto eu sei, o controle PropertyGrid ea superfície de design visual studio são as únicas coisas na BCL que consomem o material TypeDescriptor. Na verdade, é assim que eles fazem sobre a metade das coisas que realmente precisa fazer.

Você não pode. Uma solução poderia ser a de gerar uma classe derivada em tempo de execução e adicionando o atributo, embora este é provavelmente pouco de um exagero.

Bem, só para ser diferente, eu encontrei um artigo que faz referência usando Reflection.Emit a fazê-lo.

Aqui está o link: http://www.codeproject.com/KB/cs/ dotnetattributes.aspx , você também vai querer olhar para alguns dos comentários na parte inferior do artigo, porque as possíveis abordagens são discutidas.

Não, não é.

Os atributos são meta-dados e armazenados em binário-forma no assembly compilado (que também é por isso que você só pode usar tipos simples neles).

Eu não acredito que sim. Mesmo se eu estiver errado, o melhor que você pode esperar é adicioná-los a um tipo inteiro, não um exemplo de um tipo.

Se você precisa de algo para ser capaz de adicionados dinamicamente, C # atributos não são o caminho. Olhe para armazenar os dados em xml. Eu fiz recentemente um projeto que eu comecei w / atributos, mas acabou se mudando para serialização w / xml.

Por que você precisa? Atributos dar informações extra para reflexão, mas se você sabe externamente quais propriedades você quiser, não precisa deles.

Você pode armazenar dados de meta externamente com relativa facilidade em um arquivo de banco de dados ou de recursos.

Eu tentei muito duro com System.ComponentModel.TypeDescriptor sem sucesso. Isso não significa que ele pode não trabalho, mas eu gostaria de ver o código para isso.

Na parte contrária, eu queria mudar alguns valores atributo. Eu fiz 2 funções que funcionam bem para esse fim.

        // ************************************************************************
        public static void SetObjectPropertyDescription(this Type typeOfObject, string propertyName,  string description)
        {
            PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName];
            var att = pd.Attributes[typeof(DescriptionAttribute)] as DescriptionAttribute;
            if (att != null)
            {
                var fieldDescription = att.GetType().GetField("description", BindingFlags.NonPublic | BindingFlags.Instance);
                if (fieldDescription != null)
                {
                    fieldDescription.SetValue(att, description);
                }
            }
        }

        // ************************************************************************
        public static void SetPropertyAttributReadOnly(this Type typeOfObject, string propertyName, bool isReadOnly)
        {
            PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName];
            var att = pd.Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute;
            if (att != null)
            {
                var fieldDescription = att.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
                if (fieldDescription != null)
                {
                    fieldDescription.SetValue(att, isReadOnly);
                }
            }
        }

Em Java Eu costumava trabalhar em torno deste usando um mapa e implementar a minha própria visão sobre Key-Value codificação.

http://developer.apple.com/documentation/Cocoa /Conceptual/KeyValueCoding/KeyValueCoding.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top