使用SignalR,我想知道设置我的集线器的最佳方式是在以下场景下:假设我有一个网络赌场应用程序(只是为了好玩),它有三个游戏,扑克,二十一点和老虎机.扑克和二十一点都是多人游戏,因此他们有聊天功能而插槽没有.好的,为了支持这一点,我正在考虑以下列方式设置我的集线器.
BaseHub(处理扑克,二十一点和老虎机常见的连接内容)
PokerHub:BaseHub(处理扑克游戏)
BlackjackHub:BaseHub(处理二十一点游戏)
SlotsHub:BaseHub(处理老虎机游戏)
ChatHub(处理聊天功能)
我想这个网络应用程序的扑克页面连接到PokerHub以及ChatHub和Blackjack页面会做类似的事情.Slots页面显然只能连接到SlotsHub.
现在,我不确定的事情是:扑克/二十一点页面是否应该连接到PokerHub/BlackjackHub和ChatHub,或者是否有某种方式可以让他们只连接到PokerHub/BlackjackHub并将聊天功能委托给聊天毂?在这种情况下,我可能会创建一个接口IHasChat或类似的东西.在任何一种情况下,ChatHub都应该扩展BaseHub吗?目前,BaseHub仅实现IConnected,IDisconnect以及处理基本的Group功能(JoinGroup,LeaveGroup).另外,BaseHub应该是一个共享实例(单例)吗?
最后,如果你认为我只是完全错了,请告诉我.这是我的第一个SignalR项目,我知道我不是它的专家.另外,我知道这里有几个问题.如果你能回答其中的任何一个或全部,无论哪种方式,我都非常感激.
谢谢,汤姆
我正在努力实现这样的目标
public abstract class BaseEvent
{
public abstract void Dispatch(IEventHandler handler);
}
public class MyEvent : BaseEvent
{
public override void Dispatch(IMyEventHandler handler)
{
handler.OnMyEvent(this);
}
}
public interface IEventHandler
{
}
public interface IMyEventHandler : IEventHandler
{
void OnMyEvent(MyEvent e);
}
Run Code Online (Sandbox Code Playgroud)
问题是编译器抱怨说MyEvent没有实现,BaseEvent因为Dispatch它IMyEventHandler取而代之的是IEventHandler.我不想让MyEvent.Dispatch一个IEventHandler然后把它投射到一个IMyEventHandler因为我想编译时间检查以确保我没有做一些愚蠢的事情,如传递其他类型的事件处理程序.我找到了一个可能的解决方案(下面),但我想知道是否有更好的方法来做到这一点.
public abstract class BaseEvent<H> where H : IEventHandler
{
public abstract void Dispatch(H handler);
}
public class MyFirstEvent<H> : BaseEvent<H> where …Run Code Online (Sandbox Code Playgroud) 由于IEnumerable在C#4.0中有一个协变参数,我很困惑它在以下代码中的行为方式.
public class Test
{
IEnumerable<IFoo> foos;
public void DoTestOne<H>(IEnumerable<H> bars) where H : IFoo
{
foos = bars;
}
public void DoTestTwo(IEnumerable<IBar> bars)
{
foos = bars;
}
}
public interface IFoo
{
}
public interface IBar : IFoo
{
}
Run Code Online (Sandbox Code Playgroud)
所以基本上这个DoTestOne方法不会编译DoTestTwo.除了为什么它不起作用,如果有人知道如何实现DoTestOne(分配IEnumberable<H> where H : IFoo给一个IEnumberable<IFoo>)的效果,我将不胜感激.
在正常代码中静默失败的任何赋值(赋值给不可写属性,赋值给getter-only属性,赋值给非可扩展对象上的新属性)将以严格模式抛出
因此,使用他们的示例,执行类似下面的操作会引发TypeError
"use strict";
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // throws a TypeError
Run Code Online (Sandbox Code Playgroud)
然而,我遇到了一个例子,似乎"使用严格"对这条规则有点过分热心.这是我的设置
definelol.js
Object.defineProperty(Object.prototype, 'lol', {
value: 'wat'
})
Run Code Online (Sandbox Code Playgroud)
setlol.js
'use strict';
console.log('here 0');
var sugar = { lol: '123' }
console.log('here 1');
var verbose = {};
verbose.lol = '123';
console.log('here 2');
console.log('sugar.lol:', sugar.lol);
console.log('verbose.lol:', verbose.lol);
console.log('Object.prototype.lol:', Object.prototype.lol);
Run Code Online (Sandbox Code Playgroud)
app.js
require('./definelol.js');
require('./setlol.js');
Run Code Online (Sandbox Code Playgroud)
跑步node app.js给
here 0
here 1
/pathto/setlol.js:10
verbose.lol = '123';
^
TypeError: Cannot …Run Code Online (Sandbox Code Playgroud) 嵌套的辅助函数可以使您的代码更易于理解.Google甚至建议在其样式指南中使用嵌套函数.我想知道这些嵌套函数和性能的实例化.例如,
work(1);
work(2);
function work(a) {
// do some stuff
log();
// do some more stuff
function log() {
console.log(a);
}
}
Run Code Online (Sandbox Code Playgroud)
work实例化一次,但log实例化两次?
如果log每次work执行都被实例化,通常建议不要嵌套函数吗?相反,编写如下代码
work(1);
work(2);
function work(a) {
// do some stuff
log(a);
// do some more stuff
}
function log(a) {
console.log(a);
}
Run Code Online (Sandbox Code Playgroud)
这些例子过于简单,问题更多的是一般情况.
Reddit为Top帖子提供了不同的存储桶.他们有"今小时","今天","本周","本月""今年""所有时间".我可以想到创建这些列表的最佳方法是使用时间戳保存每个投票,以便您可以计算每个存储桶的帖子得分.这将是一个昂贵的查询,但他们可以逃脱它,因为Top对所有用户都是相同的,并且不会发生太大变化,因此他们可以缓存查询结果.
这只是我对正在发生的事情的最好猜测,但我很好奇,这是Reddit实际上在做什么还是有更好的方法?
我有以下扩展方法来帮助我检查和实例化它们为null的对象.前两个工作正常,但它们不是很有用.
public static bool IsNull<T>(this T t)
{
return ReferenceEquals(t, null);
}
public static T NewIfNull<T>(this T t, Func<T> createNew)
{
if (t.IsNull<T>())
{
return createNew();
}
return t;
}
public static void Ensure<T>(this T t, Func<T> createNew)
{
t = t.NewIfNull<T>(createNew);
}
Run Code Online (Sandbox Code Playgroud)
最终我想做点什么
IList<string> foo;
...
foo.Ensure<IList<string>>(() => new List<string>());
Run Code Online (Sandbox Code Playgroud)
但是,Ensure方法没有达到预期的效果,即设置foo为List<string>if为null 的实例,否则基本上将其设置为自身.
如果你现在知道我可以调整Ensure方法来实现这一点,我将不胜感激.
谢谢,汤姆
作品
private void Add<H>(H toAdd, IList<dynamic> list)
{
list.Add(toAdd);
}
Run Code Online (Sandbox Code Playgroud)
不行
private void Add<H>(IList<H> toAdd, IList<IList<dynamic>> list)
{
list.Add(toAdd);
}
Run Code Online (Sandbox Code Playgroud)
你可以想象,错误是
The best overloaded method match for 'System.Collections.Generic.ICollection<System.Collections.Generic.IList<dynamic>>.Add(System.Collections.Generic.IList<dynamic>)' has some invalid arguments
Run Code Online (Sandbox Code Playgroud)
如果有人知道为什么会这样,甚至更好,如何解决它,我很好奇.我认为它与Generic Variance有关,但动态使我不太确定.
谢谢,汤姆
编辑
//doesn't work
private void Add<H>(IList<H> toAdd, IList<IList<dynamic>> list) where H : object
{
list.Add(toAdd);
}
//works
//this isn't good enough however because I only want to be able to
//have one type of object in toAdd
private void Add(IList<object> toAdd, IList<IList<dynamic>> list)
{
list.Add(toAdd); …Run Code Online (Sandbox Code Playgroud) 我问在你试图用foreach循环迭代的对象为空时抛出异常是什么原因?
例如,以下代码抛出异常:
public void Test()
{
IEnumerable<int> numbers = null;
foreach (var number in numbers)
{
//Do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
现在修复很简单,只需在foreach循环之前检查null.
public void Test()
{
IEnumerable<int> numbers = null;
if (numbers != null)
{
foreach (var number in numbers)
{
//Do stuff
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的想法是,你可以用foreach循环做的一切,你只需要一个常规的for循环,因此foreach循环基本上存在,因为它更方便编写和更容易阅读.重要的是写它更方便.如果创建的东西很方便,为什么不一直这样做,在这种情况下隐式执行null检查.现在可能存在一些情况,如果集合为null,你实际上想要抛出异常但是,我觉得那些是目前为止的少数,它们应该是你需要显式并检查null的情况.类似于以下内容:
public static void Test()
{
IEnumerable<int> numbers = null;
if (numbers == null)
throw new NullReferenceException();
foreach (var number in numbers)
{
//Do stuff
}
}
Run Code Online (Sandbox Code Playgroud) c# ×5
javascript ×2
c#-4.0 ×1
covariance ×1
dynamic ×1
foreach ×1
function ×1
generics ×1
ienumerable ×1
node.js ×1
overriding ×1
performance ×1
reddit ×1
signalr ×1
subclass ×1
use-strict ×1