将类型传递给方法,然后调用已知存在于该类型上的方法

时间:2017-09-21 19:42:05

标签: c#

我讨厌发布与以前所提出的内容非常相似的内容,但我已经阅读了15个不同的答案,但仍未设法解决我的问题。

我有两个文件。第一个声明泛型类型并将其作为参数传递给第二个类型。第二个需要使用此传递的值对类对象进行类型转换,并在其上调用方法。这种方法没有坚定的约束力,这可能就是我的问题所在。它是“非官方”协议的一部分,例如没有被代码强制执行。

这是第一个文件:

using UnityEngine;
using UnityEditor;
using System;

[CustomEditor(typeof(RampSectionEditMode))]
public class RampSectionEditModeMeta : Editor {

    public override void OnInspectorGUI() {
        new CustomEditorMeta().HandleGenericUpdate(typeof(RampSectionEditMode).MakeGenericType(), target);
    }
}

这是使用传递类型的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class CustomEditorMeta : Editor {

    public void HandleGenericUpdate (   System.Type script_type, Object target) {
        base.OnInspectorGUI();
        if (GUILayout.Button("Update")) {
            if (target.GetType() == script_type) {
                var script = (script_type)target; // <=== PROBLEM IS HERE
                script.updateEditorState();
            }
        }
    }
}

我在(script_type)target行注意到的问题是变量被用作类型

重要提示

我无法使用动态关键字,因为我的平台有限制(Unity,据我所知,它没有官方支持此级别的C#)。

谢谢。

修改

target就是这样的一个例子:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;

[ExecuteInEditMode]
public class RampSectionEditMode : MonoBehaviour {
    public void updateEditorState () {
      // content omitted
    }
}

如果我对目标类型RampSectionEditMode进行硬编码而不是使用script_type,这确实有效,但CustomEditorMeta类的重点是抽象它。

2 个答案:

答案 0 :(得分:0)

使用反思:

if (target.GetType() == script_type) 
{
     script_type.GetMethod("updateEditorState").Invoke(target,null);
}

你也可以关注federico-dipuma的建议并创建一个界面:

public interface IUpdatable
{
    void updateEditorState()
}

并由您的班级实施:

public class RampSectionEditMode : MonoBehaviour, IUpdatable
{
   public void updateEditorState ()
  {
       // content omitted
   }
}

答案 1 :(得分:0)

如果我想在“某些”对象上调用“some”方法(例如,像WCF调用者),我经常使用这些扩展:

using System;

namespace TEST
{
    public static class Extensions
    {
        public static object Invoke(this object obj, string method, Type[] types, object[] args)
        {
            return obj?.GetType().GetMethod(method, types)?.Invoke(obj, args);
        }

        public static object Invoke(this object obj, string method, params object[] args)
        {
            return obj.Invoke(method, new Type[0], args);
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(4.Invoke("ToString"));
        }
    }
}

然后你可以打电话给你想要的任何东西。