简体   繁体   English

属性值为null时,InvokeMember“找不到方法”异常

[英]InvokeMember “Method not found” exception when property value is null

I have this classes : 我有这节课:

public abstract ClassBase {
    public virtual String PropertyA { get; set; }
}

and

public class Class : ClassBase{
    public virtual String PropertyB { get; set; }
}

When I try to set the value of PropertyA with this piece of code: 当我尝试使用以下代码设置PropertyA的值时:

instanceOfClass.GetType().InvokeMember(
    "PropertyA",
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty ,
    Type.DefaultBinder,
    instanceOfClass,
    new object[]{ "Hello world" }
);

I'm getting the error "Method not found" when instanceOfClass.PropertyA == null . instanceOfClass.PropertyA == null时,出现错误“找不到方法”。

When instanceOfClass.PropertyA!=null , it works fine. instanceOfClass.PropertyA!=null ,它工作正常。

What I'm doing wrong? 我做错了什么?

EDITED : to add the complete function as example. 编辑 :以添加完整功能为例。 It is an CRUD logic over an DataGridView control: 它是DataGridView控件上的CRUD逻辑:

public class DataGridViewCrud<T,TRepository,THandler> : UserControl
    where T : class, new() 
    where TRepository: RepositoryBase<T,THandler> 
    where THandler : NhHandlerBase
{
private readonly TRepository _repository;

private List<DataGridViewField> HiddenFields { get; set; }

private List<DataGridViewField> FieldsId { get; set; }

private DataGridView _dataGridView;

private List<T> _contents;


(...) // Other methods, functions...

private void OnCellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    try
    {
        var isNew = e.RowIndex + 1 > _contents.Count;
        var theRow = _dataGridView.Rows[e.RowIndex];

        ValidateConfig();

        using (var transaction = _repository.BeginTransaction())
        {

            T instance = null;

            if (isNew)
            {
                instance = new T();

            } else {

                // Get the ID fields name defined 
                foreach (var fieldId in FieldsId)
                {
                    // Get the current value for the current row
                    for (var i = 0; i < _dataGridView.Columns.Count; i++)
                    {
                        var columnName = _dataGridView.Columns[i].Name;

                        if (columnName != fieldId.FieldName) continue;

                        // Get instance from DB
                        var idValue = theRow.Cells[columnName].Value;
                        var criteria = _repository.GetSession().CreateCriteria<T>().Add(Restrictions.Eq(fieldId.FieldName, idValue));
                        instance = criteria.List<T>().SingleOrDefault();
                        i = _dataGridView.Columns.Count;
                    }

                }

            }

            if(instance==null) throw new Exception("Imposible to get instance from DB. Check the configuration of ID fields.");

            var properties = instance.GetType().GetProperties();

            foreach (var property in properties)
            {
                for (int i = 0; i < _dataGridView.Columns.Count; i++)
                {
                    var columnName = _dataGridView.Columns[i].Name;

                    var isColumnId = FieldsId.Any(f => f.FieldName == columnName);


                    // If is not the column (check by name), continue
                    if (columnName != property.Name) continue;

                    // Check if is Field ID and is autogenerated 
                    DataGridViewField fieldId = null;
                    if(isColumnId)
                    {
                       fieldId =  FieldsId.First(fi => fi.FieldName == columnName); 
                       if (fieldId.IsAutoGenerated) continue;
                    }


                    var cellValue = fieldId!= null ? fieldId.DefaultValue : theRow.Cells[columnName].Value;
                    var value = new object[1];

                    value[0] = cellValue;

                    instance.GetType().InvokeMember(
                        property.Name,
                        BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty ,
                        Type.DefaultBinder,
                        instance,
                        value
                    );

                }
            }

            if(isNew) { 
                _repository.Save(instance);    
            } else {
                _repository.Update(instance);
            }

            transaction.Commit();
        }

        ChangeStatus(Res.RecordSuccessfullyUpdated, false);
    }
    catch (Exception exception)
    {
        ChangeStatus(exception.Message, true);
    }

}

(...) // Other methods, functions...

} }

Indeed, the error occurred when value==DBNull 确实,当value==DBNull时发生了错误

So, to solve, replace : 所以,解决,更换:

var cellValue = fieldId!= null ? fieldId.DefaultValue : theRow.Cells[columnName].Value;
var value = new object[1];
value[0] = cellValue;

instance.GetType().InvokeMember(
    property.Name,
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty ,
    Type.DefaultBinder,
    instance,
    value
);

with this : 有了这个 :

var rowValue = theRow.Cells[columnName].Value ;
rowValue = rowValue is DBNull ? null : rowValue;

var cellValue = defaultValue ?? rowValue;
var value = new object[1];

value[0] = cellValue;

instance.GetType().InvokeMember(
    property.Name,
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty ,
    Type.DefaultBinder,
    instance,
    value
);

And now is working. 现在正在工作。 I suspect this problem was related with NHibernate map. 我怀疑这个问题与NHibernate地图有关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用InvokeMember检索静态属性值 - Retrieving static property value with InvokeMember C# InvokeMember - MissingMethodException:“未找到方法” - C# InvokeMember - MissingMethodException: 'Method not found' 非空属性的空值异常 - Null Value Exception On Property That Is Not Null InvokeMember获得特定属性值的可能值 - Possible values for InvokeMember to get specific property value 当方法具有Dictionary参数时,Type.InvokeMember - Type.InvokeMember when method has a Dictionary parameter 是什么原因导致`.toString()`方法在值为null时引发异常,而Convert..ToString()`自动处理null值 - what is reason that `.toString()` method throw an exception when value is null while Convert`.ToString()` automatic handle null value 访问OnClick中的属性时出现Null Reference异常 - Null Reference exception when accessing property in OnClick 当它是 null 时,反序列化并抛出所需属性的异常 - Deserialization and throw exception for required property when it is null 泛型类上的InvokeMember导致异常 - InvokeMember on generic class results in an exception 当值为null时,Entity Framework 6中的Nullable DateTime属性会在保存时引发异常 - Nullable DateTime property in Entity Framework 6 thows exception on save when value is null
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM