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;
}
}
}