C# 泛型类型传递和用法,我可以执行以下操作吗?

C# 泛型类型传递和用法,我可以执行以下操作吗?,c#,generics,reflection,interface,C#,Generics,Reflection,Interface,我试图找出如何在类DoSomething的CallMe()中访问静态方法。反射是这里唯一的解决方案吗?我不想实例化类型为MyAction的对象。另外,如果通过反射进行操作,是否有一种方法可以在方法CallMe()中通过反射创建方法,只需一次,然后多次调用它就可以在同一个“反射”方法上执行多个操作?还是有比通过反思更好的方法?我基本上想创建模板实现风格的类,比如MyAction,它们定义了byte[]DoThis(string text)如何履行其职责。然后,AskForSomething()将指

我试图找出如何在类
DoSomething
CallMe()中访问静态方法。反射是这里唯一的解决方案吗?我不想实例化类型为
MyAction
的对象。另外,如果通过反射进行操作,是否有一种方法可以在方法
CallMe()
中通过反射创建方法,只需一次,然后多次调用它就可以在同一个“反射”方法上执行多个操作?还是有比通过反思更好的方法?我基本上想创建模板实现风格的类,比如
MyAction
,它们定义了
byte[]DoThis(string text)
如何履行其职责。然后,
AskForSomething()
将指定正在使用的模板,并根据该模板,
CallMe()
将开始工作

    public class AskSomething
    {
        public void AskForSomething()
        {
            DoSomething doSomething = new DoSomething();
            doSomething.CallMe<MyAction>();
        }
    }

    public class DoSomething
    {
        public void CallMe<T>()
        {
            Type type = typeof(T);

            //Question: How can I access 'DoThis(string text)' here?
            //Most likely by reflection? 
        }
    }

    public class MyAction
    {
        public static byte[] DoThis(string text)
        {
            byte[] ret = new byte[0]; //mock just to denote something is done and out comes a byte array

            return ret;
        }
    }
公共类AskSomething
{
公共无效AskForSomething()
{
DoSomething DoSomething=新的DoSomething();
doSomething.CallMe();
}
}
公共级剂量测量
{
public void CallMe()
{
类型=类型(T);
//问题:如何在此处访问“DoThis(字符串文本)”?
//很可能是因为思考?
}
}
公共集体诉讼
{
公共静态字节[]点此(字符串文本)
{
byte[]ret=new byte[0];//mock只是表示完成了某件事,然后生成一个字节数组
返回ret;
}
}

定义一个与
dot的接口,让
MyAction
实现它,并将
T
类型参数约束为它与
的实例,其中T:IMyInterface
如果您的
dot
方法需要是静态的,您还可以将
CallMe
方法更改为以下内容:

public void CallMe(Func<string, byte[]> action)
{
    byte[] result = action("input");
}
公共类DoSomething
{
类缓存
{
public readonly static Func action=(Func)Delegate.CreateDelegate(typeof(Func),typeof(T).GetMethod(“DoThis”);
}
public void CallMe()
{
缓存。操作(“文本”);
}
}
基于“DoThis”不必是静态的这一事实,您可以通过以下方式实现这一点:-

using System;

namespace ConsoleApplication3
{
class Program
{
    static void Main(string[] args)
    {
        DoSomething doSomething = new DoSomething();
        doSomething.CallMe<MyAction>();

    }
}
public class DoSomething
{
    public void CallMe<T>() where T : IMyAction
    {
       IMyAction action =  (IMyAction)Activator.CreateInstance(typeof(T));

       var result = action.DoThis("value");            
    }
}

public interface IMyAction
{
    byte[] DoThis(string text);
}

public class MyAction : IMyAction
{
    public byte[] DoThis(string text)
    {
        byte[] ret = new byte[0]; //mock just to denote something is done and out comes a byte array

        return ret;
    }
}
}
使用系统;
命名空间控制台应用程序3
{
班级计划
{
静态void Main(字符串[]参数)
{
DoSomething DoSomething=新的DoSomething();
doSomething.CallMe();
}
}
公共级剂量测量
{
public void CallMe()其中T:IMyAction
{
IMyAction action=(IMyAction)Activator.CreateInstance(typeof(T));
var结果=action.DoThis(“值”);
}
}
公共接口激励
{
字节[]点此(字符串文本);
}
公共集体诉讼:IMYAAction
{
公共字节[]点此(字符串文本)
{
byte[]ret=new byte[0];//mock只是表示完成了某件事,然后生成一个字节数组
返回ret;
}
}
}

我不确定我会推荐这种方法,但它是有效的!(例如,如果没有默认构造函数,则会失败)

+1我试图解释为什么这不起作用,但仅仅描述如何使其起作用显然要简单得多…接口是正确的方法,但如果必须将DoThis作为静态方法,那么就必须使用反射。@KierenJohnstone,好的,看来接口是可行的方法。但我想这意味着我必须通过一个T的实例,对吗?@RossDargan,这不一定是静态的。我只是想考虑一下必须传入MyAction类的一个实例。我所需要的就是访问DoThis方法。
new T().DoThis(“abc”)
,或者您可以传入一个实例。您需要使用
where T:IMyInterface,new()
进行约束,以确保它具有无参数的结构或技术上正确的、无法维护和设计的垃圾。当然:)@KierenJohnstone我们不是在寻找简单的方法什么?是的,所有软件开发人员都应该始终寻找一种简单的方法。你可以用剪刀钉钉子-有人甚至会问,钉钉子最好用哪把剪刀-但当然,每次你都应该用锤子..@DarkGray,而界面解决方案在这种情况下看起来更合适,如果我决定将来使用反射,您是否介意解释一下您的解决方案将如何工作(我对编程非常熟悉)。我现在如何在一个循环中调用这个被调用的方法,该循环迭代了一百万次,而不必在每次迭代中再次调用该方法?我想这是我在最初的问题中已经提过的。@DarkGray,老实说,我不知道你的答案如何避免在每次迭代中一次又一次地调用,因为方法调用是在一个循环中完成的。我也不确定你是不是在假期前就开始胡闹了……你坚持认为这是一个比界面更好的解决方案,这真是太奇怪了……无论如何,谢谢!这类似于一名代表还是一名代表?是的,这是一名代表。您可以使用此委托来表示可以作为参数传递的方法,而无需显式声明自定义委托(请参阅)。感谢您的解释,您是否碰巧知道委托和接口实现之间的性能差异?我记得在上一节课上遇到过一个类似的问题,但我再也找不到了。这里是讨论过的stackoverflow问题,但在担心性能之前,这是一个很好的阅读:谢谢,这正是我以前遇到的问题,如果性能确实是一个问题,也谢谢你给我推荐性能档案(在这里,我每秒处理大约1500-2000万个项目,因此即使是微秒级的差异也会累积起来。)这是一种反射方法吗?顺便说一句,我认为您需要调用
doSomething.CallMe()
,而不是
doSomething.CallMe()
,对吗?是的,Activator.CreateInsta
  public class DoSomething
  {
    class Cache<T>
    {
      public readonly static Func<string, byte[]> action = (Func<string, byte[]>)Delegate.CreateDelegate(typeof(Func<string, byte[]>), typeof(T).GetMethod("DoThis"));
    }
    public void CallMe<T>()
    {
      Cache<T>.action("text");
    }
  }
using System;

namespace ConsoleApplication3
{
class Program
{
    static void Main(string[] args)
    {
        DoSomething doSomething = new DoSomething();
        doSomething.CallMe<MyAction>();

    }
}
public class DoSomething
{
    public void CallMe<T>() where T : IMyAction
    {
       IMyAction action =  (IMyAction)Activator.CreateInstance(typeof(T));

       var result = action.DoThis("value");            
    }
}

public interface IMyAction
{
    byte[] DoThis(string text);
}

public class MyAction : IMyAction
{
    public byte[] DoThis(string text)
    {
        byte[] ret = new byte[0]; //mock just to denote something is done and out comes a byte array

        return ret;
    }
}
}