C# 从GenericClass返回非空接口对象<;T>;还是更好的编程模式?

C# 从GenericClass返回非空接口对象<;T>;还是更好的编程模式?,c#,wcf,design-patterns,interface,C#,Wcf,Design Patterns,Interface,我有一个通用类,如下所示 Subscriber<T> where T : class { public T callback {get; set;} public USER User {get; set;} } 编辑: 我在我的客户机中创建这个对象,并将其传递到我的服务订阅方法中。无法在客户端中设置回调,因为我在那里没有回调对象(至少据我所知)。所以在我的服务订阅方法中,我有Subscriber.Callback=OperationContext.Current

我有一个通用类,如下所示

Subscriber<T> where T : class
{
    public T callback {get; set;} 
    public USER User {get; set;}
}
编辑: 我在我的客户机中创建这个对象,并将其传递到我的服务订阅方法中。无法在客户端中设置回调,因为我在那里没有回调对象(至少据我所知)。所以在我的服务订阅方法中,我有
Subscriber.Callback=OperationContext.Current
也许我在类中存储该值的设计模式是错误的——如何实现

编辑:根据Daniels请求发布代码。代码中的注释指示问题所在的位置。在WCFServer的Subscribe方法中,我得到了NRE。当然 在创建用户的表单中,我无法将回调设置为新的回调,因为它尚未创建,只是一个接口。如何在客户机窗体中创建带有回调参数的用户类,以便在服务器中使用它来存储回调。我是否应该将其声明为object并强制转换为T?还是我的逻辑错了?感谢您的帮助

客户表格:

public partial class Form1 : Form
{
Form1()
{
this.ServiceSubscriber = new WCF.Subscriber<WCF.Interfaces.IDataCallback>();
// Problem occurs that I cant set the callback here. 
// this.ServiceSubscriber.Callback 
}
public void WCFClientLogin(WCF.Subscriber<WCF.Interfaces.IDataCallback> subscriber)
{
    if (WCFClient == null)
    {
        WCFClient = new WCF.ClientProxy();
    }
    WCFClient.StartClient(subscriber);
}
}
interface IDataCallBack
{
 [OperationContract(IsOneWay=true)]
 void Subscribe(WCF.Subscriber<WCF.Interfaces.IDataCallback> subscriber);
}
public class Subscriber<T> : ISubscriber<T> where T : class
{
 public T Callback {get; set;}
 public Guid UniqueIdentifier {get; set;}
 public Subscriber(T callback)
 {
   this.UniqueIdentifier = Guid.NewGuid();
   this.Callback = callback;
 }
}
public void Subscribe(Subscriber<IDataCallback> registrant)
{
    lock (_syncSubscribe)
    {
        try
        {
            IDataCallback callback = OperationContext.Current.GetCallbackChannel<IDataCallback>();
                        // RegisteredUser is Dictionary<Guid, IDataCallback>
// I can't set it here either because I get null reference exception.
            RegisteredUser[registrant.UniqueIdentifier].Callback = callback;
        }
        catch(Exception e) // TODO: More Explicit Catch
        {
           OnServerException(e);

        }               
    }           
}
公共部分类表单1:表单
{
表格1()
{
this.ServiceSubscriber=new WCF.Subscriber();
//问题是我不能在这里设置回调。
//此为.ServiceSubscriber.Callback
}
public void WCFClientLogin(WCF.Subscriber)
{
如果(WCFClient==null)
{
WCFClient=new WCF.ClientProxy();
}
WCFClient.StartClient(订户);
}
}
界面:

public partial class Form1 : Form
{
Form1()
{
this.ServiceSubscriber = new WCF.Subscriber<WCF.Interfaces.IDataCallback>();
// Problem occurs that I cant set the callback here. 
// this.ServiceSubscriber.Callback 
}
public void WCFClientLogin(WCF.Subscriber<WCF.Interfaces.IDataCallback> subscriber)
{
    if (WCFClient == null)
    {
        WCFClient = new WCF.ClientProxy();
    }
    WCFClient.StartClient(subscriber);
}
}
interface IDataCallBack
{
 [OperationContract(IsOneWay=true)]
 void Subscribe(WCF.Subscriber<WCF.Interfaces.IDataCallback> subscriber);
}
public class Subscriber<T> : ISubscriber<T> where T : class
{
 public T Callback {get; set;}
 public Guid UniqueIdentifier {get; set;}
 public Subscriber(T callback)
 {
   this.UniqueIdentifier = Guid.NewGuid();
   this.Callback = callback;
 }
}
public void Subscribe(Subscriber<IDataCallback> registrant)
{
    lock (_syncSubscribe)
    {
        try
        {
            IDataCallback callback = OperationContext.Current.GetCallbackChannel<IDataCallback>();
                        // RegisteredUser is Dictionary<Guid, IDataCallback>
// I can't set it here either because I get null reference exception.
            RegisteredUser[registrant.UniqueIdentifier].Callback = callback;
        }
        catch(Exception e) // TODO: More Explicit Catch
        {
           OnServerException(e);

        }               
    }           
}
接口IDataCallBack
{
[运营合同(IsOneWay=true)]
无效订阅(WCF.Subscriber);
}
订户类别:

public partial class Form1 : Form
{
Form1()
{
this.ServiceSubscriber = new WCF.Subscriber<WCF.Interfaces.IDataCallback>();
// Problem occurs that I cant set the callback here. 
// this.ServiceSubscriber.Callback 
}
public void WCFClientLogin(WCF.Subscriber<WCF.Interfaces.IDataCallback> subscriber)
{
    if (WCFClient == null)
    {
        WCFClient = new WCF.ClientProxy();
    }
    WCFClient.StartClient(subscriber);
}
}
interface IDataCallBack
{
 [OperationContract(IsOneWay=true)]
 void Subscribe(WCF.Subscriber<WCF.Interfaces.IDataCallback> subscriber);
}
public class Subscriber<T> : ISubscriber<T> where T : class
{
 public T Callback {get; set;}
 public Guid UniqueIdentifier {get; set;}
 public Subscriber(T callback)
 {
   this.UniqueIdentifier = Guid.NewGuid();
   this.Callback = callback;
 }
}
public void Subscribe(Subscriber<IDataCallback> registrant)
{
    lock (_syncSubscribe)
    {
        try
        {
            IDataCallback callback = OperationContext.Current.GetCallbackChannel<IDataCallback>();
                        // RegisteredUser is Dictionary<Guid, IDataCallback>
// I can't set it here either because I get null reference exception.
            RegisteredUser[registrant.UniqueIdentifier].Callback = callback;
        }
        catch(Exception e) // TODO: More Explicit Catch
        {
           OnServerException(e);

        }               
    }           
}
公共类订户:i订户,其中T:class
{
公共T回调{get;set;}
公共Guid唯一标识符{get;set;}
公共用户(T回调)
{
this.UniqueIdentifier=Guid.NewGuid();
this.Callback=Callback;
}
}
WCF服务:

public partial class Form1 : Form
{
Form1()
{
this.ServiceSubscriber = new WCF.Subscriber<WCF.Interfaces.IDataCallback>();
// Problem occurs that I cant set the callback here. 
// this.ServiceSubscriber.Callback 
}
public void WCFClientLogin(WCF.Subscriber<WCF.Interfaces.IDataCallback> subscriber)
{
    if (WCFClient == null)
    {
        WCFClient = new WCF.ClientProxy();
    }
    WCFClient.StartClient(subscriber);
}
}
interface IDataCallBack
{
 [OperationContract(IsOneWay=true)]
 void Subscribe(WCF.Subscriber<WCF.Interfaces.IDataCallback> subscriber);
}
public class Subscriber<T> : ISubscriber<T> where T : class
{
 public T Callback {get; set;}
 public Guid UniqueIdentifier {get; set;}
 public Subscriber(T callback)
 {
   this.UniqueIdentifier = Guid.NewGuid();
   this.Callback = callback;
 }
}
public void Subscribe(Subscriber<IDataCallback> registrant)
{
    lock (_syncSubscribe)
    {
        try
        {
            IDataCallback callback = OperationContext.Current.GetCallbackChannel<IDataCallback>();
                        // RegisteredUser is Dictionary<Guid, IDataCallback>
// I can't set it here either because I get null reference exception.
            RegisteredUser[registrant.UniqueIdentifier].Callback = callback;
        }
        catch(Exception e) // TODO: More Explicit Catch
        {
           OnServerException(e);

        }               
    }           
}
公开作废订阅(订户注册人)
{
锁定(同步订阅)
{
尝试
{
IDataCallback callback=OperationContext.Current.GetCallbackChannel();
//RegisteredUser是一本字典
//我也不能在这里设置它,因为我得到空引用异常。
RegisteredUser[registent.UniqueIdentifier].Callback=Callback;
}
catch(异常e)//TODO:更显式的catch
{
onserver异常(e);
}               
}           
}
“我无法创建接口实例(duh),但我认为可能有办法解决这个问题”-不,没有办法。您无法对接口进行反序列化,除非它们与已知的默认实现(例如,
IList
)是“特殊的”,即使如此,它是否能工作也取决于您的确切上下文


接收端需要知道用于实现接口的类型,否则无法确保反序列化对象的行为与序列化对象相同。只要修改合同,使其使用具体类型而不是接口。

如果您从未设置
回调
,无论它是
对象
还是
t
,您仍然会得到NRE。例如,您为什么不在构造函数中接受
T
的实例?这一点都没有帮助。您的问题非常不清楚。@yuval T是一个接口;因此,当我直接存储在字典中时,我可以做到这一点并访问它。当我将IMyCallback封装在Subscriber类中时,我无法设置它,因为我得到了NRE,我将这个Subscriber对象从客户机传递到服务中-它不是在客户机上设置的,因为此时回调不可用。因此,在subscribe方法中的服务中,我想设置回调。Subscriber.Callback=(IMyCallBack)上下文@Stix:请提供一个简短但完整的示例来说明您的问题。你的描述不清楚,“我不能创建接口实例(duh),但我想可能有办法解决这个问题”——不,没有办法。您无法对接口进行反序列化,除非它们与已知的默认实现(例如,
IList
)是“特殊的”,即使如此,它是否能工作也取决于您的确切上下文。接收端需要知道用于实现接口的类型,否则无法确保反序列化对象的行为与序列化对象相同。只需修改合同,使其使用具体类型而不是接口。