Conselhos sobre C Árvores # Expressão
-
03-07-2019 - |
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 ..
- 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? - Trata-se de um padrão específico que estou usando?
- 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!
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.