Return 来自 GenericClass<T> 的非空接口对象或更好的编程模式?
Return non null Interface object from GenericClass<T> or better programming pattern?
我有一个通用 class 如下。
Subscriber<T> where T : class
{
public T callback {get; set;}
public USER User {get; set;}
}
T 实际上是一个用于传入和传出回调的接口。然而正如你所知,当我去使用这个 Null Reference Exception 时抛出。所以我去搜索 stack'O 以创建接口 T 的实例,如你所知我无法创建接口的实例(duh)但我想也许有办法解决这个问题。我正在使用 WCF 并希望存储回调对象,但通常会这样做,因为 Subscriber 方法可用于其他回调协定。我应该存储为对象并在获取时转换为类型 T 吗?
private object _callback;
public object Callback
get
{
return (T)_callback;
}
set
{
_callback = value;
}
编辑:
我在我的客户端中创建了这个对象,并将其传递到我的服务订阅方法中。无法在客户端中设置回调,因为我那里没有回调对象(至少我知道)。所以在我的服务订阅方法中,我有 Subscriber.Callback = OperationContext.Current;
也许我在 class 中存储此值的设计模式是错误的 - 怎么办?
编辑: 根据 Daniels 请求发布的代码。代码中的注释指出问题所在。在 WCFServer 的订阅方法中 - 我得到了 NRE。当然。
在创建用户的表单中 - 我无法将回调设置为新回调,因为它尚未创建并且只是一个接口。如何在我的客户端表单中使用回调参数创建用户 Class,以便它可以在我的服务器中用于存储回调。我应该将它声明为对象并转换为 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);
}
订阅者CLASS:
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;
}
}
WCF 服务:
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 can't create an instance of an interface (duh) but I thought maybe there was a way around this" — 不,没有办法解决这个问题。您不能反序列化接口,除非它们 "special" 具有已知的默认实现(例如 IList<T>
),即便如此,它是否有效将取决于您的确切上下文。
接收端需要知道用于实现接口的类型,否则无法确保反序列化对象的行为与序列化对象相同。只需修复您的合同,使其使用具体类型而不是接口。
我有一个通用 class 如下。
Subscriber<T> where T : class
{
public T callback {get; set;}
public USER User {get; set;}
}
T 实际上是一个用于传入和传出回调的接口。然而正如你所知,当我去使用这个 Null Reference Exception 时抛出。所以我去搜索 stack'O 以创建接口 T 的实例,如你所知我无法创建接口的实例(duh)但我想也许有办法解决这个问题。我正在使用 WCF 并希望存储回调对象,但通常会这样做,因为 Subscriber 方法可用于其他回调协定。我应该存储为对象并在获取时转换为类型 T 吗?
private object _callback;
public object Callback
get
{
return (T)_callback;
}
set
{
_callback = value;
}
编辑:
我在我的客户端中创建了这个对象,并将其传递到我的服务订阅方法中。无法在客户端中设置回调,因为我那里没有回调对象(至少我知道)。所以在我的服务订阅方法中,我有 Subscriber.Callback = OperationContext.Current;
也许我在 class 中存储此值的设计模式是错误的 - 怎么办?
编辑: 根据 Daniels 请求发布的代码。代码中的注释指出问题所在。在 WCFServer 的订阅方法中 - 我得到了 NRE。当然。 在创建用户的表单中 - 我无法将回调设置为新回调,因为它尚未创建并且只是一个接口。如何在我的客户端表单中使用回调参数创建用户 Class,以便它可以在我的服务器中用于存储回调。我应该将它声明为对象并转换为 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);
}
订阅者CLASS:
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;
}
}
WCF 服务:
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 can't create an instance of an interface (duh) but I thought maybe there was a way around this" — 不,没有办法解决这个问题。您不能反序列化接口,除非它们 "special" 具有已知的默认实现(例如 IList<T>
),即便如此,它是否有效将取决于您的确切上下文。
接收端需要知道用于实现接口的类型,否则无法确保反序列化对象的行为与序列化对象相同。只需修复您的合同,使其使用具体类型而不是接口。