Как решить «Указанный актерский состав недействителен». ошибка - PullRequest
0 голосов
/ 05 ноября 2019

У меня есть простой проект, я динамически выполняю string value с C# compiler.

, следуя коду:

private void btntest_Click(object sender, EventArgs e)
        {
            string code = @"
using System;
using System.Text;
using System.Data;
using System.Reflection;
using System.ComponentModel;

namespace myNameSpace
{
    public class DynamicClass
    {
        public bool myFunction(DataRow dr)
        {
            if (dr == null)
                return false;

            if (dr.Table.Columns.Contains(""Col1"")  && (bool)dr[""Col1""] == true)
                return true;
            else
                return false;
        }
    }
}
";

            Assembly asm = BuildAssembly(code);
            object instance = null;
            Type type = null;
            instance = asm.CreateInstance("myNameSpace.DynamicClass");
            type = instance.GetType();
            DataTable dt = new DataTable();
            dt.Columns.Add("Col1");
            DataRow dr = dt.NewRow();
            dr[0] = true;

            MethodInfo method = type.GetMethod("myFunction");
            object returnVal = method.Invoke(instance, new object[] { dr });
            txtError.Text = returnVal.ToString();

        }

        Assembly BuildAssembly(string code)
        {
            CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
            CompilerParameters compilerparams = new CompilerParameters();
            compilerparams.GenerateExecutable = false;
            compilerparams.GenerateInMemory = false; 

            compilerparams.ReferencedAssemblies.Add("mscorlib.dll");
            compilerparams.ReferencedAssemblies.Add("System.dll");
            compilerparams.ReferencedAssemblies.Add("System.Data.dll");
            compilerparams.ReferencedAssemblies.Add("System.Xml.dll");

            CompilerResults results = codeProvider.CompileAssemblyFromSource(compilerparams, code);
            if (results.Errors.HasErrors)
            {
                StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
                foreach (CompilerError error in results.Errors)
                {
                    errors.AppendFormat("Line {0},{1}\t: {2}\n",
                           error.Line, error.Column, error.ErrorText);
                }
                throw new Exception(errors.ToString());
            }
            else
            {
                return results.CompiledAssembly;
            }
        }

, когда я запускаю проект, я получаю следующую ошибку:

Исключение было сгенерировано целью вызова.

Внутреннее исключение

InvalidCastException: указанное приведение недействительно.

Если я удаляю секцию (bool)dr[""Col1""] == true, она работает хорошо.

Что assembly или namespace должны быть добавлены?

Как исправить эту ошибку?

Любая помощь очень ценится.

Ответы [ 2 ]

1 голос
/ 05 ноября 2019

Проблема в этой строке:

dt.Columns.Add("Col1");

Если вы не укажете тип, по умолчанию он будет string. Это означает, что значение ячейки преобразуется в строку True. Так что вы должны делать это:

dt.Columns.Add("Col1", typeof(bool));
0 голосов
/ 05 ноября 2019

Как вы уже указали, эта строка вызывает проблему:

if (dr.Table.Columns.Contains("Col1")  && (bool)dr["Col1"] == true)

Явное приведение dr["Col1"] к bool не выполняется, поскольку значение не являетсябулево . Явное приведение завершается неудачно.

Если предположить, что dr["Col1"] действительно содержит bool, но не всегда, вы можете проверить его тип перед преобразованием, используя синтаксис, подобный следующему:

dr["Col1"] is bool myValue && myValue == true

Приведенный выше код подтвердил, что dr["Col1"] является bool, а затем определил myValue как это bool значение.

Код может стать еще чище, удалив myValue == true и просто имея myValue (каконо будет оценено как true или false). В указанном вами коде:

if (dr.Table.Columns.Contains(""Col1"") && dr[""Col1""] is bool myValue && myValue)

Если dr["Col1"] на самом деле не содержит bool, но на самом деле содержит int или что-то еще в качестве индикатора значения, являющегося истиннымвам нужно будет реализовать другую логику.

...