我有一个实现的自定义类,ICollection这个类是只读的,即.IsReadOnly返回true(与使用readonly关键字相反),以及通常会修改集合中数据的所有函数InvalidOperationException.
现在,给定这样的结构,并在实现ICollection(特别是ICollection.IsSynchronized朋友)时快速浏览线程安全问题,我提出了这个快速而肮脏的解决方案.
bool ICollection.IsSynchronised { get{ return true; } }
object ICollection.SyncRoot { get{ return new Object(); } }
Run Code Online (Sandbox Code Playgroud)
现在,考虑到MSDN中的示例,这不会导致不同的线程正确锁定,因为它们从中获取不同的对象SyncRoot.鉴于这是一个只读集合,这是一个问题吗?返回时是否存在内存/ GC问题new Object()?您可以通过此实现看到的任何其他问题?
我想问的问题是:
是从一个可抽象的类,甚至是一个好的东西,从一个抽象类内部下来继承树(即,朝着一个更特殊的类),或者它总是一个可怜的选择,有更好的选择?
现在,举例说明为什么我认为它可以用得很好.
我最近在C#中使用BitTorrent协议实现了Bencoding.一个简单的问题,如何表示数据.我选择这样做,
我们有一个abstract BItem类,它提供了一些基本功能,包括static BItem Decode(string)用于将Bencoded字符串解码为必要结构的类.
还有四个派生类BString,BInteger,BList和BDictionary,表示待编码的四个不同的数据类型.现在,这是棘手的部分.BList并且分别BDictionary具有this[int]和this[string]访问器以允许访问这些数据类型的类似阵列的质量.
潜在的可怕部分现在即将到来:
BDictionary torrent = (BDictionary) BItem.DecodeFile("my.torrent");
int filelength = (BInteger)((BDictionary)((BList)((BDictionary)
torrent["info"])["files"])[0])["length"];
Run Code Online (Sandbox Code Playgroud)
嗯,你得到的照片......哎呀,这对眼睛很难,更不用说大脑了.所以,我在抽象类中引入了一些额外的东西:
public BItem this[int index]
{
get { return ((BList)this)[index]; }
}
public BItem this[string index]
{
get { return ((BDictionary)this)[index]; }
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以将旧代码重写为:
BDictionary torrent = (BDictionary)BItem.DecodeFile("my.torrent");
int filelength = (BInteger)torrent["info"]["files"][0]["length"];
Run Code Online (Sandbox Code Playgroud)
哇,嘿presto,更多可读代码.但是,我是否只是将我的灵魂的一部分用于将子类的知识隐含在抽象类中?
编辑:为了回应一些答案,你完全偏离了这个特定的问题,因为结构是可变的,例如我的例子torrent["info"]["files"][0]["length"]是有效的,但同样如此 …
我正在尝试使用C#,Linux上的单声道/ GTK#和Windows上的.NET/GTK#创建跨平台C#应用程序,但是在两个平台下启动顺序似乎需要略有不同:
在Linux下:
public static void Main (string[] args)
{
Gdk.Threads.Init ();
// etc...
Run Code Online (Sandbox Code Playgroud)
在Windows下:
public static void Main (string[] args)
{
Glib.Thread.Init ();
Gdk.Threads.Init ();
// etc...
Run Code Online (Sandbox Code Playgroud)
两者都要求以这种方式完成:Windows抱怨g_thread_init()没有使用linux代码调用,并且linux抱怨已经使用Windows代码调用它.除此之外,这一切都非常有效.
我对"解决方案"的第一次尝试看起来像:
public static void Main (string[] args)
{
try {
Gdk.Threads.Init ();
} catch (Exception) {
GLib.Thread.Init ();
Gdk.Threads.Init ();
}
// etc...
Run Code Online (Sandbox Code Playgroud)
但即便是这个凌乱的解决方案也行不通; 错误来自GTK +,非托管代码,因此无法捕获.有没有人对问题的原因有什么好主意,以及如何解决它?或者,如果不这样做,有关于如何检测应在运行时调用哪一个的明智想法?
假设Y是来自类X的派生类,X将foo声明为虚拟.假设y是(Y*)类型.然后((X*)y) - > foo()将执行Y版本的foo(),但是((X)*y).foo()将执行X版本.你能告诉我为什么多态性不适用于解引用的案例吗?我希望任何一种语法都会产生Y版本的foo().
随着多处理器和多核计算机变得越来越普遍,简单地开辟一个新线程(一种(相对)简单而无痛的简化代码的方式?例如,在当前的个人项目中,我有一个网络服务器在端口上侦听.由于这只是一个个人项目,它只是一个桌面应用程序,其中集成了GUI进行配置.所以,应用程序读取如下内容:
Main()
Read configuration
Start listener thread
Run GUI
Listener Thread
While the app is running
Wait for a new connection
Run a client thread for the new connection
Client Thread
Write synchronously
Read synchronously
ad inifinitum, or till they disconnect
这种方法意味着虽然我不得不担心很多锁定问题,但是由于潜在的问题,我避免了很多来自同步调用的意大利面条代码等.
今天,当我处理启动代码时,出现了一个稍微更阴险的版本.启动很快,但它使用延迟加载很多配置,这意味着虽然启动很快,实际连接和使用服务是困难的,因为它加载不同的部分滞后(这实际上可以测量实际时间,有时长达3-10秒).所以我在启动时采用了不同的策略,循环遍历所有内容并强制延迟加载......但这使得它开始过于缓慢; 起床,慢慢喝咖啡.最终解决方案:将循环放入单独的线程中,并在系统托盘仍然加载时反馈.
这是"嗯,扔进另一个线程,它会很好"的态度好吗?您在什么时候开始获得收益递减和/或甚至降低性能?
随着即将发布的Visual Studio 2010以及C#4.0中所有可爱的新功能,我真的很想从2008年开始更新.但是,在过去的几年里,我已经成功获得学生定价,甚至免费版本MSDN学术联盟.
现在我不再是学生了.
我似乎无法证明即使是标准版的$ AU500价格也是合理的,这本质上是一种爱好.尽管我可能喜欢它,但它只是不付账单.
所以,我读过微软的网站,有一个在Express版本EULA,因为我认为应该有报酬的工作偶尔位,这是很好没有非商业条款上.与Professional相比,Express版本缺少多少(我目前使用的是什么,以及2010 beta版是什么)?当我找到那些不存在的东西时,我是否可能会经历戒断痛苦?
对于插件来说,唯一一个我真正玩过的是VisualSVN,我可以忍受手动使用TortoiseSVN.还有什么我应该知道的吗?
鉴于我们假设的一些(英语)单词是复数,是否可以推导出单数形式?如果可能的话,我想避免查找/字典表.
一些例子:
Examples -> Example a simple 's' suffix Glitch -> Glitches 'es' suffix, as opposed to above Countries -> Country 'ies' suffix. Sheep -> Sheep no change: possible fallback for indeterminate values
对语言库的建议x是好的,只要它们是开源的(即,有人可以检查它们以确定如何用语言进行y)
假设我想出了一些代表我认为对其他人了解和使用有用的数据的超级方式.假设我有某种形式的'规范',即使它可能不是一个完全正式的:即,我知道这种文件格式将如何工作.
那么我将如何发布此规范以获得基于它的评论和反馈?我怎样才能以某种形式"标准化"?
我有一个课程Logger,其中包括一个方法Log.
作为实例Log的最常见用途Logger,我已__invoke拨打电话Log
另一个类"Site"包含一个成员"Log",一个Logger实例.
为什么这样做:
$Log = $this->Log;
$Log("Message");
Run Code Online (Sandbox Code Playgroud)
但不是这个:
$this->Log("Message");
Run Code Online (Sandbox Code Playgroud)
前者失败了"PHP致命错误:调用未定义的方法Site :: Log()"
这是可调用对象实现的限制,还是我误解了什么?
我有两个程序(服务器/客户端)我正在尝试为它们设置 IPC(它们都在同一个盒子上运行)使用 System.IO.Pipes & Net 3.5
当我调用 ComOpen 时,它会正确打开管道,将进程 ID 发送到服务器,但随后管道关闭,当它尝试发送“第二次写入测试”时出现错误
所以问题是。我如何在程序的整个生命周期内保持管道打开?(如果客户端崩溃,我使用服务器上的进程 ID 关闭所有内容)
private static StreamWriter MyWriter;
private static StreamReader MyReader;
private static NamedPipeClientStream IPCPipe = new NamedPipeClientStream(".", "MyPipe", PipeDirection.InOut);
public static bool MyWrite(string DataOut)
{
bool ValidPipeOut = false;
if(ValidComPort)
try
{
// Send Data
using (QstWriter = new StreamWriter(IPCPipe))
{
QstWriter.AutoFlush = true;
QstWriter.WriteLine(QstDataOut);
QstWriter.Close();
QstWriter.Dispose();
}
ValidPipeOut = true;
}
catch
{
ValidPipeOut = false;
}
return ValidPipeOut;
}
public static bool ComOpen()
{
ValidComPort = …Run Code Online (Sandbox Code Playgroud) c# ×4
.net-2.0 ×1
bittorrent ×1
c++ ×1
callable ×1
file-format ×1
gtk# ×1
inheritance ×1
invoke ×1
nlp ×1
php ×1
pipe ×1
polymorphism ×1
stemming ×1