Pergunta

Esta questão já tem uma resposta aqui:

precisamos avaliar um valor em um objeto em tempo de execução, enquanto nós temos uma declaração textual do caminho membro exata por exemplo: myobject.firstMember.secondMember [3] .text
nós pensamos de analisar esta declaração textual usando regex e, em seguida, avaliar o valor de texto usando reflexão, mas antes de fazer isso eu me pergunto se C # apoiar algum tipo de eval capacidade? por isso não terá que fazer a nós mesmos a análise. Como microsoft fazer isso em seus janela janelas ou assistir imediatos?

Muito obrigado,

Adi Barda

Foi útil?

Solução

Provavelmente a maneira mais fácil é usar DataBinder .Eval de System.Web.UI:

var foo = new Foo() { Bar = new Bar() { Value = "Value" } };
var value = DataBinder.Eval(foo, "Bar.Value");

Outras dicas

Eu escrevi um projeto open source, dinâmico Expresso , que pode converter expressão de texto escrito usando um C # sintaxe em delegados (ou árvore de expressão). Expressões são analisados ??e transformados em href="http://msdn.microsoft.com/en-us/library/bb397951.aspx" Árvores sem usar compilação ou reflexão.

Você pode escrever algo como:

var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");

ou

var interpreter = new Interpreter()
                .SetVariable("service", new ServiceExample());

string expression = "x > 4 ? service.SomeMethod() : service.AnotherMethod()";

Lambda parsedExpression = interpreter.Parse(expression, 
                        new Parameter("x", typeof(int)));

parsedExpression.Invoke(5);

O meu trabalho se baseia no artigo Scott Gu http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic- query-library.aspx .

No futuro (ao redor do 5.0 prazo), o "compilador como um serviço" pode ser capaz de fazer isso. Na verdade, você pode ser capaz de fazer um monte de presente agora com "mono" (ver CsharpRepl Mono.CSharp - no entanto, espero que 'necessidade ll saber muito mais sobre o contexto para ser capaz de usar as variáveis ??locais etc em Evaluate ) -. mas não há qualquer apoio para este na atual oferta de MS .NET

Por enquanto, você teria que fazer algo como o que uma grande parte do código de ligação de dados que ... dividi-lo distante por símbolos como "". e usar a reflexão. Estritamente falando, o código de ligação realmente usa TypeDescriptor / PropertyDescriptor ao invés de reflexão direta, mas o efeito é o mesmo.

Embora uma abordagem um pouco pesado de peso, você pode usar C # CodeDom para emitir um novo um novo conjunto que contém um método com apenas essa linha de código.

Isso é muito mais mão pesada do que algumas das outras sugestões, eu admito, mas por outro lado você deixar o C # analisador fazer o trabalho pesado, por isso deve ser capaz de lidar com tudo o que você jogue com ele, desde que é válido C #.

Se você ir por esse caminho, você também precisa se certificar que você pode descarregar o emitido montagem novamente, para criar e AppDomains descarga pode ser necessária.

Eu tenho implementado com sucesso e usado a técnica acima. Por outro lado, se você pode usar um DynamicMethod seria muito mais leve. No entanto, eu nunca tentei essa abordagem, então eu não posso dizer se você pode implementar o corpo de uma DynamicMethod usando C # literais.

Na verdade, o recurso de motor de avaliação e regras de expressão do Windows Workflow Foundation pode fazer coisas como esta. Consulte Introdução ao Windows Workflow Foundation Rules Engine.

Uma coisa interessante sobre esses componentes é que eles foram projetados de modo que você pode hospedar os componentes de tempo de design em seus próprios aplicativos para projetar conjuntos de regras e / ou expressões que operam no contexto de suas próprias classes personalizadas. Por exemplo, você diria a ele para projetar uma expressão contra "myObject", e saberia que há um firstMember que tem uma secondMember que tem um indexador produzindo um tipo que tem uma propriedade de texto. Você pode persistir as expressões e regras como XML, e lê-los de volta em tempo de execução, sem a necessidade de usar o designer em tempo de execução.

Em particular, veja externa RuleSet Toolkit Sample .

Infelizmente, C # não tem nenhum instalações nativas para fazer exatamente o que você está pedindo.

No entanto, o meu programa # eval C não permite a avaliação de código C #. Ele fornece para avaliar código C # em tempo de execução e suporta muitas declarações C #, incluindo expressões como " myobject.firstMember.secondMember [3] .text ". Na verdade, este código é utilizável em qualquer projeto .NET, no entanto, é limitado a usar C # sintaxe. Dê uma olhada no meu site, http://csharp-eval.com , para obter detalhes adicionais.

Você pode sempre tentar o meu peso-leve programa C # Eval. Ele compila um subconjunto substancial da linguagem C # para métodos dinâmicos. Detalhes completos sobre o meu GitHub repositório DavidWynne / CSharpEval

AFAIK não existe tal função Eval embutido. Você terá que seguir o caminho da reflexão Regex +. Eu também acho que Visual Studio está fazendo o mesmo.

Há algo aqui semelhante que estou usando para encontrar propriedades dinamicamente aninhados .. você precisaria addthe lógica para indexadores ... e alguma verificação adicional ... eu estou pegando nulos / erros no meu método chamando ...

  public static object FindDottedProperty(this object input, string propertyName)
  {
    if (input == null)
      return null;

    if (string.IsNullOrEmpty(propertyName))
      return null;

    Queue props = new Queue(propertyName.Split('.'));
    if (props.Count == 0) return null;

    //start with input object and roll out property stack from there.
    object ret = input;
    while (props.Count > 0)
    {
      var prop = props.Dequeue();
      if (string.IsNullOrEmpty(prop)) return null;

      /*** ADD INDEXER LOGIC HERE ***/

      //get the property's value based on the current named item
      ret = ret.GetType().GetProperty(prop).GetValue(ret, null);

      if (null.Equals(ret)) return null;
    }

    //return looked up value
    return ret;
  }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top