C# 使用动态确定的类类型静态定义成员

C# 使用动态确定的类类型静态定义成员,c#,events,.net-3.5,types,C#,Events,.net 3.5,Types,我试图创建一个事件委托,其中参数是强类型的,以匹配当前类,如下所示: public class HPCRequest { public delegate void RequestCompleteHandler(HPCRequest request); public event RequestCompleteHandler RequestComplete; request.RequestComplete += new HPCGetConfig.RequestComplet

我试图创建一个事件委托,其中参数是强类型的,以匹配当前类,如下所示:

public class HPCRequest
{
    public delegate void RequestCompleteHandler(HPCRequest request);
    public event RequestCompleteHandler RequestComplete;
    request.RequestComplete += new HPCGetConfig.RequestCompleteHandler(HPCGetConfig_RequestComplete);
    request.SendRequestAsync();
}

void HPCGetConfig_RequestComplete(HPCGetConfig request)
{
    request.RequestComplete -= HPCGetConfig_RequestComplete;
public abstract class HPCRequest<T> where T : HPCRequest<T>
{
    public delegate void RequestCompleteHandler(T request);
    public event RequestCompleteHandler RequestComplete;
}

public class DerivedHPCRequest : HPCRequest<DerivedHPCRequest>
{

}
问题是这个类的要点是要继承的,我真正想要的是所有继承类都有“RequestComplete”事件,其中为该类键入委托:

public class HPCGetConfig : HPCRequest
{
    //I want this class to effectively inherit something like this:
    //public delegate void RequestCompleteHandler(HPCGetConfig request);
这是因为目前,当我有一个处理我的“RequestComplete”事件的函数时,我必须执行以下操作:

    myGetConfigRequest.RequestComplete += new HPCRequest.RequestCompleteHandler(HPCGetExpectedLosses_RequestComplete);

void HPCGetConfig_RequestComplete(HPCRequest request)
{
    HPCGetConfig thisRequest = request as HPCGetConfig;
    //This should be strongly typed in the first place.
但我希望能够做到这一点:

public class HPCRequest
{
    public delegate void RequestCompleteHandler(HPCRequest request);
    public event RequestCompleteHandler RequestComplete;
    request.RequestComplete += new HPCGetConfig.RequestCompleteHandler(HPCGetConfig_RequestComplete);
    request.SendRequestAsync();
}

void HPCGetConfig_RequestComplete(HPCGetConfig request)
{
    request.RequestComplete -= HPCGetConfig_RequestComplete;
public abstract class HPCRequest<T> where T : HPCRequest<T>
{
    public delegate void RequestCompleteHandler(T request);
    public event RequestCompleteHandler RequestComplete;
}

public class DerivedHPCRequest : HPCRequest<DerivedHPCRequest>
{

}

尝试

我试过这个:

public delegate void RequestCompleteHandler<T>(T request) where T : HPCRequest; 
public event RequestCompleteHandler<T> RequestComplete;
当我尝试调用事件时也会发生相同的错误:
RequestComplete(this)

我还尝试了创建委托和事件并覆盖它们的所有形式,例如:

public class HPCRequest
{
    public delegate void RequestCompleteHandler(HPCRequest request);
    public virtual event RequestCompleteHandler RequestComplete;


public sealed class HPCGetConfig : HPCRequest
{
    public delegate void RequestCompleteHandler(HPCGetConfig request);
    public override event RequestCompleteHandler RequestComplete;
但这给了我一个编译时错误,因为我不能用不同的委托类型覆盖RequestComplete事件

还有其他想法吗


编辑

模板化整个HPCRequest类不是一个选项,在进行了一次非常彻底的尝试之后,我发现每次尝试将HPCRequest类型用作任何请求类型的占位符时,都会出错。如果此解决方案要起作用,则类
HPCRequest
必须能够实例化并从中继承,而无需指定类型参数。我需要一个不需要模板化的解决方案
HPCRequest


为了确保每个人都确切地知道我是如何使用它的,我将一些示例代码粘贴到了pastebin中,这样您就可以尝试在不破坏任何内容的情况下使用此事件模板的方法。这里是:

您可以为此使用泛型类型参数,因此从HPCRequest继承的每个类都必须指定泛型类型参数。此外,我建议使用
abstract
修饰符标记设计为基类的类,以避免显式实例化:

public abstract class HPCRequest<TRequest>
  where TRequest: class
{
    public delegate void RequestCompleteHandler(TRequest request);
    public event RequestCompleteHandler<TRequest> RequestComplete;
}


public sealed class HPCGetConfig : HPCRequest<HPCGetConfig>
{
}
公共抽象类HPCRequest
特雷奎斯特:课堂在哪里
{
公共委托无效请求完成处理程序(TRequest请求);
公共事件RequestCompleteHandler RequestComplete;
}
公共密封类HPCGetConfig:HPCRequest
{
}

您可以将抽象类的类型参数约束为从抽象类本身派生。看起来很奇怪,但你可以这样设置:

public class HPCRequest
{
    public delegate void RequestCompleteHandler(HPCRequest request);
    public event RequestCompleteHandler RequestComplete;
    request.RequestComplete += new HPCGetConfig.RequestCompleteHandler(HPCGetConfig_RequestComplete);
    request.SendRequestAsync();
}

void HPCGetConfig_RequestComplete(HPCGetConfig request)
{
    request.RequestComplete -= HPCGetConfig_RequestComplete;
public abstract class HPCRequest<T> where T : HPCRequest<T>
{
    public delegate void RequestCompleteHandler(T request);
    public event RequestCompleteHandler RequestComplete;
}

public class DerivedHPCRequest : HPCRequest<DerivedHPCRequest>
{

}
公共抽象类HPCRequest,其中T:HPCRequest
{
公共委托无效请求完成处理程序(T请求);
公共事件RequestCompleteHandler RequestComplete;
}
公共类派生的HPCRequest:HPCRequest
{
}
您可以尝试的内容:

public abstract class HPCRequest<T> where T : HPCRequest<T>
{
  public delegate void RequestCompleteHandler(T request);
  public event RequestCompleteHandler RequestComplete;

  protected void RaiseRequestComplete(T request)
  {
    if (RequestComplete != null)
    {
      RequestComplete(request);
    }
  }
}

public class Foo : HPCRequest<Foo>
{
  public void Bar()
  {
    RaiseRequestComplete(this);
  }
}

public class Example
{
  public static void Test()
  {
    var request = new Foo();

    request.RequestComplete += RequestComplete;
  }

  static void RequestComplete(Foo request)
  {
    // It's a Foo!
  }
}
公共抽象类HPCRequest,其中T:HPCRequest
{
公共委托无效请求完成处理程序(T请求);
公共事件RequestCompleteHandler RequestComplete;
受保护的无效请求完成(T请求)
{
if(RequestComplete!=null)
{
请求完成(请求);
}
}
}
公共类Foo:HPCRequest
{
公共空白栏()
{
RAISEReRequestComplete(此);
}
}
公开课范例
{
公共静态无效测试()
{
var request=newfoo();
request.RequestComplete+=RequestComplete;
}
静态无效请求完成(Foo请求)
{
//这是一个Foo!
}
}
我认为,这种自引用的泛型约束可以满足您的需求。我添加了
受保护的RaiseRequestCompleted
,这样您仍然可以从继承自HCPRequest的类中引发事件。否则,只允许
HCPRequest
这样做


更新:我更新了代码以通过
,并添加了与所需结果匹配的示例代码。

我认为您必须创建一个抽象基类,该基类不能被实例化:

public abstract class HPCRequestBase<T> where T : HPCRequestBase<T>
{
    public delegate void RequestCompleteHandler(T request);
    public event RequestCompleteHandler RequestComplete;

    protected void OnRequestComplete(T request)
    {
        if (RequestComplete != null) {
            RequestComplete(request);
        }
    }

    public void Test( )
    {
        OnRequestComplete((T)this);
    }

}

public class HPCRequest : HPCRequestBase<HPCRequest>
{
    public void Test2()
    {
        OnRequestComplete(this);
    }
}

public class HPCRequestConfig : HPCRequestBase<HPCRequestConfig>
{
    // Derived from the base class, not from HPCRequest 
}

您的用例非常适合在泛型基类中显式实现非泛型接口。我不确定我是否完全理解所需的功能,但我想我确实理解了。我写了一些代码(如下),应该可以让你开始

作为旁注,没有真正的理由声明代理。为了与一致,您的解决方案将使用
EventHandler
和自定义
EventArgs
实现

代码
//这是一个使用我推荐的模式的示例程序
//我很确定这就是你想要你的代码的样子?
公共课程
{
公共静态void Main()
{
var request=new HPCGetConfig();
request.RequestComplete+=HandleConfigRequestCompleted;
SendAsync();
}
静态无效HandleConfigRequestCompleted(对象发送方,RequestCompleteEventTargets e)
{
var请求=e.请求;
//对请求做点什么
}
}
//非泛型事件args类
公共抽象类RequestCompleteEventTargets:EventArgs
{
公共抽象类型RequestType{get;}
公共抽象对象请求对象{get;set;}
}
//泛型事件args类
公共类RequestCompleteEventArgs:RequestCompleteEventArgs
{
私人信托请求;
公共电话请求
{
获取{返回m_请求;}
设置{m_Request=value;}
}
公共重写类型RequestType
{
获取{return typeof(T);}
}
公共覆盖对象请求对象
{
获取{返回请求;}
设置
{
如果(!(值为T))
{
抛出新ArgumentException(“无效类型”,“值”);
}
m_请求=(T)值;
}
}
}
//非泛型接口
公共接口IHPCRequest
{
事件处理程序请求完成;
}
//泛型基类
公共抽象类HPCRequest:IHPCRequest
其中T:HPCRequest
{
//这将清理事件处理程序,并使其可调用
//每当事件处理程序订阅非泛型
//接口
普里瓦