Pergunta

Eu estou trabalhando em um método que aceita uma árvore de expressão como um parâmetro, juntamente com um tipo (ou instância) de uma classe.

A idéia básica é que este método irá adicionar certas coisas a uma coleção que será usado para validação.

public interface ITestInterface
{
    //Specify stuff here.
}

private static void DoSomething<T>(Expression<Func<T, object>> expression, params IMyInterface[] rule)
{
    // Stuff is done here.
}

O método é chamado como se segue:

class TestClass
{
    public int MyProperty { get; set; }
}

class OtherTestClass  : ITestInterface
{
    // Blah Blah Blah.
}

static void Main(string[] args)
{
    DoSomething<TestClass>(t => t.MyProperty, 
        new OtherTestClass());
}

Estou fazendo isso dessa maneira porque eu gostaria que os nomes das propriedades que são passados ??para ser forte digitado.

Um par de coisas que eu estou lutando com ..

  1. Dentro DoSomething, eu gostaria de obter um tipo PropertyInfo (do corpo aprovada em) de T e adicioná-lo a uma coleção junto com a regra []. Atualmente, estou pensando em usar expression.Body e remoção [propertyname] em "Convert. ([Propertyname])" e usando a reflexão para obter o que eu preciso. Isso parece complicado e errado. Existe uma maneira melhor?
  2. Trata-se de um padrão específico que estou usando?
  3. Por último, todas as sugestões ou esclarecimentos quanto à minha incompreensão do que eu estou fazendo são apreciados e / ou recursos ou boas informações sobre C # árvores de expressão são apreciados também.

Obrigado!

Ian

Editar:

Um exemplo de retornos que expression.Body.ToString() dentro do método DoSomething é uma cadeia que contém "Convert (t.MyProperty)" se chamado a partir do exemplo acima.

Mas eu preciso que ele seja fortemente tipado, por isso não irá compilar se eu mudar o nome da propriedade.

Obrigado pelas sugestões!

Foi útil?

Solução

Coleta de PropertyInfo objetos de Expression.Body parece semelhante a minha solução a outra pergunta.

Outras dicas

I dependem fortemente de árvores de expressão para empurrar muito do que eu quero fazer com o meu aplicativo atual para compilar-time, ou seja estática verificação de tipo.

Eu atravessar árvores de expressão para traduzi-los em outra coisa que "faz sentido".

Uma coisa que eu acabei fazendo um monte é que em vez de URLs I contar com um MVC como abordagem onde eu declarar funções lambda, e traduz isso ... interpretar, a árvore de expressão compilador gerado em uma URL. Quando essa URL é invocado, eu faço o oposto. Desta forma, eu tenho o que eu chamo verificações de tempo de compilação para links quebrados e isso funciona muito bem com refatoração e sobrecargas também. Eu acho que é legal para pensar em usar árvores de expressão dessa forma.

Você pode querer verificar o padrão do visitante, é uma dor para começar com porque não faz muito sentido no início, mas que amarra tudo junto e é uma maneira muito formal para resolver a verificação de tipo na construção de compiladores. Você poderia fazer o mesmo, mas em vez de verificação de tipo Emit que nunca você precisa.

Algo que atualmente estou batendo minha cabeça contra é a capacidade de construir uma estrutura simples para traduzir (ou, na verdade, devo dizer interpretar) árvores expressão e emitem JavaScript. A ideia é que o compilador gerado árvores de expressão se traduzirá em JavaScript válida que as interfaces com algum modelo de objeto.

O que é interessante sobre esta é a forma como o compilador é sempre capaz de me dizer quando eu errei e com certeza o resultado final é apenas um monte de cordas, mas a parte mais importante é a forma como essas seqüências foi criada. Eles passaram por alguma verificação e isso significa alguma coisa.

Depois de conseguir que vai há pouco que você não pode fazer com árvores de expressão.

Ao trabalhar com a System.Reflection.Emit coisas que eu me vi usando árvores de expressão para criar uma estrutura leve para a compilação dinâmica, que em tempo de compilação pode basicamente dizer se minhas montagens criados dinamicamente seria compilar também, e isso funcionou perfeitamente com reflexão e verificação de tipo estático. Ele tomou esta mais e mais e acabou com algo que no fim salvou um monte de tempo e provou ser muito ágil e robusto.

Então, eu amo este tipo de coisas, e é isso que a programação meta é tudo, escrever programas em seus programas que fazem programas. Eu digo mantê-lo chegando!

Eu aprecio o que você está tentando fazer com a propriedade aqui. Eu executar para esse enigma. Ele sempre se sente estranho para escrever:

DoSomething("MyProperty", new OtherClass());

Se a propriedade nunca muda o nome ou o texto é digitado incorretamente na chamada, em seguida, haverá um problema. O que eu tenho vindo a aprender é que isso é algo que você provavelmente terá que lidar com via testando. Especificamente, o teste de unidade. Eu ia escrever testes de unidade para impor que as chamadas "doSomething" funcione corretamente.

A outra coisa que você pode tentar é para decorar suas propriedades com atributos e, em seguida, refletir contra a sua classe quando ela é construída à procura de propriedades com o atributo e regras de carga.

[DoSomething(typeof(OtherClass), typeof(OtherClass2))]
public int MyProperty
{
  get;
  set;
}

Neste caso, o construtor (talvez em uma classe base?) Iria criar dinamicamente um objeto OutraClasse e um objeto OtherClass2, e carregá-los em uma coleção, juntamente com o nome da propriedade.

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