【问题标题】:C# Get an object which is a property and execute a method in the object from a string valueC#获取作为属性的对象并从字符串值执行对象中的方法
【发布时间】:2016-09-04 06:49:57
【问题描述】:

我有一个具有属性对象的类。这些对象中的每一个都有方法。我想从一个字符串值/变量中获取这个属性,它是一个对象并执行它的方法。

var property = this.GetType().GetProperty( "SomePropertyObject" );
MethodInfo getMethod = property.GetMethod;
var obj = getMethod.Invoke......
var runMethod = obj.GetType().GetMethod( "SomeMethod" );
runMethod.Invoke(obj, new object[] { value1 } );

问题在于,当我获得属性时,我只有 get 和 set 方法可以使用。如果我可以通过 get 方法获取对象,我可以运行 objects 方法。请你告诉我这是否可能,我该怎么做?

非常感谢您的帮助。

编辑:

基本上我想在我的实体框架 DbContext 类中添加审计。我已经成功地为较小的项目创建了单表审计,但现在我想使用反射创建每个表审计。我可以使用 AuditId 和 Action(更新、添加、软删除等)创建与其各自的模型相同的审计模型。我使用反射在 Model 和 ModelAudit 之间传输属性值。

我想更改当前将 ModelAudit 添加到相应 DbSet 集合的 switch 语句。

private void SaveAudit( DbEntityEntry entry )
    {
        try
        {
            var name = entry.Entity.GetType().Name;
            var space = entry.Entity.GetType().Namespace;
            var type = Type.GetType( string.Format( "{0}.Audits.{1}Audit", space, name ) );

            object audit = null;

            if ( type != null )
            {
                audit = Activator.CreateInstance( type );

                var props =
                    entry.Entity.GetType()
                        .GetProperties( BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy );

                audit.GetType().GetProperty( "Action" ).SetValue( audit, entry.State.ToString() );

                foreach ( var prop in props )
                {
                    if ( prop.CanWrite && prop.CanRead )
                        switch ( prop.PropertyType.ToString() )
                        {
                            case "System.String":
                            case "System.string":
                            case "System.Int32":
                            case "System.Nullable`1[System.Int32]":
                            case "System.Int64":
                            case "System.bool":
                            case "System.Nullable`1[System.Boolean]":
                            case "System.DateTime":
                            case "System.Nullable`1[System.DateTime]":
                                audit.GetType().GetProperty( prop.Name ).SetValue( audit, prop.GetValue( entry.Entity ) );
                                break;
                        }
                }

                // TODO: Replace with reflection.
                if ( !entry.State.ToString().Equals( "Unchanged" ) )
                {
                    switch ( name )
                    {
                        case "Account":
                            AccountAudits.Add( ( AccountAudit ) audit );

【问题讨论】:

  • 你能展示一个示例对象吗?
  • 鉴于您使用的是this,为什么不直接致电this.SomePropertyObject.SomeMethod(value1);。如果我的评论不适用于您的问题,您可能需要举一个更好的例子
  • 我希望我的编辑能更好地解释我的情况......

标签: c# methods reflection properties invoke


【解决方案1】:

这是通过反射完成的,并且可以通过以下方式完成:

Type type = Assembly.GetType(some_type);
MethodInfo method = type.GetMethod(name_of_method);
ParameterInfo[] parameters = method?.GetParameters();
object instance = Activator.CreateInstance(type, null);

var result = method.Invoke(instance, parameters);

这未经测试,但我相信这是您正在寻找的答案的一般方法。

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题,您可以执行以下操作:

    public static object RunMethod(object o, string propertyName, string methodName, object[] methodArguments = null)
    {
        var properyInfo = o.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Static)
    
        if (properyInfo == null)
            //No such property, bail out appropiately
    
        var invokeTarget = properyInfo.GetValue(o);
    
        if (invokeTarget == null)
            //Property returned null, bail out appropiately
    
        var argumentTypes = methodArguments == null ? Enumerable.Empty<Type>() : methodArguments.Select(a => a.GetType());
        var methodInfo = invokeTarget.GetType().GetMethod(methodName, argumentTypes.ToArray());
    
        if (methodInfo == null)
           //No such method, bail out appropiately
    
        return methodInfo.Invoke(invokeTarget, methodArguments);
    }
    

    【讨论】:

    • 好答案,但我没有对象的句柄,因为在实例化类时对象被实例化为属性。
    • @JayKayOf4 我不关注你。我正在通过属性获取实例。也许使用o 会让你感到困惑,根据你的例子,它真的是this
    • 我已经编辑了我的初始帖子,希望它能解释我的情况。
    猜你喜欢
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 2012-01-27
    • 2016-10-24
    • 1970-01-01
    相关资源
    最近更新 更多