C# 如何将对象强制转换为其自己的类型?
我已经读了好几篇关于这个问题的帖子,但是没有一个答案适合我。情况是这样的--我有一个泛型函数要在另一个类中调用:C# 如何将对象强制转换为其自己的类型?,c#,generics,casting,C#,Generics,Casting,我已经读了好几篇关于这个问题的帖子,但是没有一个答案适合我。情况是这样的--我有一个泛型函数要在另一个类中调用: public class Dispatcher<T> where T : Event { public void Notify<X>(X tEvent) where X : Event { if (someField is IListener<X, T>) { //this never execut
public class Dispatcher<T> where T : Event {
public void Notify<X>(X tEvent) where X : Event {
if (someField is IListener<X, T>) {
//this never executes--X is Event regardless of its derived type
}
}
}
问题是Event有几十个派生类型,我需要Notify()调用,派生类型为X。到目前为止,无论传入何种类型的事件,它都只调用Notify当然这里有一个使用反射的解决方案。您是否可以删除约束并检查以确保它源自
事件,如下所示:
public class Dispatcher<T> where T : Event {
public void Notify<X>(X tEvent) {
if(typeof(tEvent).IsSubclassOf(typeof(Event))
{
if (someField is IListener<X, T>) {
//this never executes--X is Event regardless of its derived type
}
}
}
}
公共类调度程序,其中T:Event{
公共无效通知(X tEvent){
if(类型(事件).IsSubclassOf(类型(事件))
{
如果(某个字段是IListener){
//这永远不会执行--X是事件,无论其派生类型如何
}
}
}
}
您是否可以删除约束并检查以确保它源自事件,如下所示:
public class Dispatcher<T> where T : Event {
public void Notify<X>(X tEvent) {
if(typeof(tEvent).IsSubclassOf(typeof(Event))
{
if (someField is IListener<X, T>) {
//this never executes--X is Event regardless of its derived type
}
}
}
}
公共类调度程序,其中T:Event{
公共无效通知(X tEvent){
if(类型(事件).IsSubclassOf(类型(事件))
{
如果(某个字段是IListener){
//这永远不会执行--X是事件,无论其派生类型如何
}
}
}
}
您有两个问题
首先,您的泛型正在泄漏。每当您需要确定特定实例的类型时,您的函数不再是泛型的。请考虑您的设计缺陷并重新检查您正在尝试做什么。
其次,IListener
不是类型。泛型在.NET中不是泛型的;运行时确定应用程序需要的所有实际类型并创建它们。例如,如果您在应用程序中实际使用类型IListener
,runtim将创建该类型
var foo = new List<int>();
var bar = foo.GetType() == typeof(List<>);
var foo=newlist();
var bar=foo.GetType()==typeof(列表);
在本例中,bar
为false
即使有了这些,是的,这也是可能的。您只需要了解泛型类型定义的反射是如何工作的
我强烈建议您重新考虑以这种方式使用泛型。有时抽象和荒谬并不是最好的事情…您有两个问题
首先,您的泛型正在泄漏。每当您需要确定特定实例的类型时,您的函数不再是泛型的。请考虑您的设计缺陷并重新检查您正在尝试做什么。
其次,IListener
不是类型。泛型在.NET中不是泛型的;运行时确定应用程序需要的所有实际类型并创建它们。例如,如果您在应用程序中实际使用类型IListener
,runtim将创建该类型
var foo = new List<int>();
var bar = foo.GetType() == typeof(List<>);
var foo=newlist();
var bar=foo.GetType()==typeof(列表);
在本例中,bar
为false
即使有了这些,是的,这也是可能的。您只需要了解泛型类型定义的反射是如何工作的
我强烈建议您重新考虑以这种方式使用泛型。有时抽象和荒谬并不是最好的事情…为了像您期望的那样调用它,您必须使用反射来生成myEvent的实际类型的方法。但我要强调的是,执行以下操作是一个坏主意,可能意味着我们的设计需要重新考虑
MethodInfo openGenericMethod = OtherClass.GetType().GetMethod("Notify");
MethodInfo closedGenericMethod = openGenericMethod.MakeGenericMethod(myEvent.GetType());
closedGenericMethod.Invoke(OtherClass, new object[]{ myEvent });,
我并没有实际测试上面的代码,但它看起来是这样的,为了像您期望的那样调用它,您必须使用反射来生成myEvent的实际类型的方法。但是我要强调的是,执行以下操作是一个坏主意,可能意味着您的设计需要重新考虑
MethodInfo openGenericMethod = OtherClass.GetType().GetMethod("Notify");
MethodInfo closedGenericMethod = openGenericMethod.MakeGenericMethod(myEvent.GetType());
closedGenericMethod.Invoke(OtherClass, new object[]{ myEvent });,
我实际上没有测试上面的代码,但它看起来是这样的,所以我似乎找到了另一端的解决方法
public class Dispatcher<T> where T : Event {
public void Notify<X>(X tEvent) where X : Event {
foreach (Object l in listeners) {
if (l is IListener<X, T>) { //never true
(l as IListener<X, T>).OnEvent();
}
}
}
}
公共类调度程序,其中T:Event{
公共无效通知(X tEvent),其中X:事件{
foreach(侦听器中的对象l){
如果(l是线性的){//永远不会为真
(l作为IListener.OnEvent();
}
}
}
}
我有一个烂摊子:
public class Dispatcher<T> where T : Event {
public void Notify<X>(X tEvent) where X : Event {
foreach (Object l in listeners) {
foreach (Type t in l.GetType().GetInterfaces()) {
Type[] temp = t.GetGenericArguments();
if (temp.Count() > 0 && temp[0] == tEvent.GetType()) {
MethodInfo mi = t.GetMethod("OnEvent", new Type[] {tEvent.GetType()});
mi.Invoke(l, new object[] { tEvent });
}
}
}
}
}
公共类调度程序,其中T:Event{
公共无效通知(X tEvent),其中X:事件{
foreach(侦听器中的对象l){
foreach(在l.GetType().GetInterfaces()中键入t){
类型[]temp=t.GetGenericArguments();
if(temp.Count()>0&&temp[0]==tEvent.GetType()){
MethodInfo mi=t.GetMethod(“OnEvent”,新类型[]{tEvent.GetType()});
调用(l,新对象[]{tEvent});
}
}
}
}
}
虽然我不喜欢测试每个界面(Windows窗体至少有10个界面),但这似乎是可行的。我将尝试BrandonAGr的解决方案,因此我似乎已经找到了另一端的解决方法。而不是
public class Dispatcher<T> where T : Event {
public void Notify<X>(X tEvent) where X : Event {
foreach (Object l in listeners) {
if (l is IListener<X, T>) { //never true
(l as IListener<X, T>).OnEvent();
}
}
}
}
公共类调度程序,其中T:Event{
公共无效通知(X tEvent),其中X:事件{
foreach(侦听器中的对象l){
如果(l是线性的){//永远不会为真
(l作为IListener.OnEvent();
}
}
}
}
我有一个烂摊子:
public class Dispatcher<T> where T : Event {
public void Notify<X>(X tEvent) where X : Event {
foreach (Object l in listeners) {
foreach (Type t in l.GetType().GetInterfaces()) {
Type[] temp = t.GetGenericArguments();
if (temp.Count() > 0 && temp[0] == tEvent.GetType()) {
MethodInfo mi = t.GetMethod("OnEvent", new Type[] {tEvent.GetType()});
mi.Invoke(l, new object[] { tEvent });
}
}
}
}
}
公共类调度程序,其中T:Event{
公共无效通知(X tEvent),其中X:事件{
foreach(侦听器中的对象l){
foreach(在l.GetType().GetInterfaces()中键入t){
类型[]temp=t.GetGenericArguments();
if(temp.Count()>0&&temp[0]==tEvent.GetType()){
MethodInfo mi=t.GetMethod(“OneEvent”,新类型[]{t