C# 反射和CODEDOM在项目里的一点实际应用

很早就研究过CodeDom,当时觉得挺有意思的,但是一时也想不到具体应用在哪,于是写了个DEMO就放在那里了。

昨天项目里有个地方要把一大堆值拿来计算公式,每一个值还都是需要单独计算求和,并且最后的公式还不一定,最后还需要输出所有的值,搞的我有点头大,其实也不算太麻烦,但是手工定义一大堆变量再去操作我怎么想怎么不爽,突然想起CodeDom,于是尝试了下, 果然爽多了。

首先构造类,将所有要计算的值都构造成变量,把变量的赋值加减和公式的计算都放在类的一个方法里,构造完类之后调用一下方法,该计算的就都计算完了,最后用反射输出所有值就OK了。

虽然是个简单的应用,不过还是很有感觉,嘿嘿,不写重复的东西就是爽。

private string GetSumScript(Dictionary<string, DeviceInfo> dictAllDevs)
    {
        StringBuilder classSrc = new StringBuilder();
        classSrc.Append(" using  System;" + Environment.NewLine);
        classSrc.Append(" namespace  A { " + Environment.NewLine);
        classSrc.Append("public  class  TempSum{ " + Environment.NewLine);//创建temp类
        List<string> propList = new List<string>();
        string strSum = "public void Run(){";//temp类中的计算方法
        foreach (KeyValuePair<string, DeviceInfo> item in dictAllDevs)
        {
            SumValues(ref classSrc, ref strSum, ref propList, item, 4);
            SumValues(ref classSrc, ref strSum, ref propList, item, 10);
            SumValues(ref classSrc, ref strSum, ref propList, item, 20);
        }
        strSum += "}";
        classSrc.Append(strSum + Environment.NewLine);
        classSrc.Append("}" + Environment.NewLine);
        classSrc.Append("}" + Environment.NewLine);
        object obj = BulidClass(classSrc);//创建类,调用计算方法
        return GetObjFillScript(obj);//输出计算结果
    }
    private void SumValues(ref StringBuilder classSrc, ref string strSum, ref  List<string> propList, KeyValuePair<string, DeviceInfo> item, int valueIndex)
    {
        double value = 0;
        string strProp = "SUMVALUE" + item.Value.Level.ToString() + item.Value.Tagindex + valueIndex.ToString();//类中的变量名
        switch (valueIndex)
        {
            case 4:
                value = item.Value.LoadValue4;
                break;
            case 10:
                value = item.Value.LoadValue10;
                break;
            default:
                value = item.Value.LoadValue20;
                break;
        }
        if (!propList.Contains(strProp))
        {
            classSrc.Append("public double " + strProp + "=" + value + ";" + Environment.NewLine);//如果不存在就声明它
            propList.Add(strProp);
        }
        else
        {
            strSum += GetFormula(strProp, value, item);//存在则使用公式计算
        }
    }
    private object BulidClass(StringBuilder classSrc)
    {
        string source = classSrc.ToString();
        CSharpCodeProvider compiler = new CSharpCodeProvider();
        CompilerParameters paras = new CompilerParameters();
        paras.GenerateExecutable = false;
        paras.GenerateInMemory = true;
        CompilerResults result = compiler.CompileAssemblyFromSource(paras, source);
        Assembly assembly = result.CompiledAssembly;
        object eval = assembly.CreateInstance("A.TempSum");
        MethodInfo method = eval.GetType().GetMethod("Run");//调用计算方法
        object reobj = method.Invoke(eval, null);
        return eval;
    }
    private string GetObjFillScript(object obj)
    {
        string str = "";
        Type type = obj.GetType();
        foreach (FieldInfo fi in type.GetFields())//用反射输出所有值
        {
            str += "content.add('" + fi.Name.ToUpper() + "','" + fi.GetValue(obj) + "',null);";
        }
        return str;
    }

你可能感兴趣的:(C# 反射和CODEDOM在项目里的一点实际应用)