.NET中使用了一种相当常见的模式来测试类的功能.这里我将使用Stream类作为示例,但该问题适用于使用此模式的所有类.
该模式是提供一个名为CanXXX的布尔属性,以指示该类上的功能XXX可用.例如,Stream类具有CanRead,CanWrite和CanSeek属性,以指示可以调用Read,Write和Seek方法.如果属性值为false,则调用相应的方法将导致抛出NotSupportedException.
从流类的MSDN文档:
根据底层数据源或存储库,流可能仅支持其中一些功能.应用程序可以使用CanRead,CanWrite和CanSeek属性查询流的功能.
和CanRead属性的文档:
在派生类中重写时,获取一个值,指示当前流是否支持读取.
如果从Stream派生的类不支持读取,则对Read,ReadByte和BeginRead方法的调用会抛出NotSupportedException.
我看到很多代码都是按照以下方式编写的:
if (stream.CanRead)
{
stream.Read(…)
}
Run Code Online (Sandbox Code Playgroud)
请注意,没有同步代码,例如,以任何方式锁定流对象 - 其他线程可能正在访问它或它引用的对象.也没有捕获NotSupportedException的代码.
MSDN文档未声明属性值不能随时间更改.实际上,当流关闭时,CanSeek属性会更改为false,从而演示这些属性的动态特性.因此,没有合同保证在上面的代码片段中调用Read()不会抛出NotSupportedException.
我希望有很多代码可以解决这个潜在的问题.我想知道那些发现这个问题的人是如何解决它的.这里适合哪些设计模式?
我也很感激评论这种模式的有效性(CanXXX,XXX()对).对我来说,至少在Stream类的情况下,这代表了一个试图做太多的类/接口,应该分成更基本的部分.缺乏紧密的,有文件记录的合同使测试变得不可能,实施更加困难!
我目前正在学习如何使用Autofac,而且我坚持要IDisposable确定性地处理对象.在我陈述我的问题之前,让我首先介绍一下情况.
假设我的对象模型是通过以下接口定义的:
interface IApple : IDisposable
{
void Consume();
}
interface IHorse
{
void Eat(IApple apple); // is supposed to call apple.Consume()
}
interface IHorseKeeper
{
void FeedHorse(); // is supposed to call horse.Eat(apple)
// where 'horse' is injected into IHorseKeeper
// and 'apple' is generated by IHorseKeeper on-the-fly
}
Run Code Online (Sandbox Code Playgroud)
此外,我定义了一个将用作IApple工厂的委托:
delegate IApple AppleFactory;
Run Code Online (Sandbox Code Playgroud)
现在,如下我将寄存器的上述类型-请注意,我省略这两个类的代码Apple和Horse,因为他们是容易实现:
var builder = new Autofac.ContainerBuilder();
builder.RegisterType<Apple>().As<IApple>();
builder.RegisterType<Horse>().As<IHorse>();
builder.RegisterType<HorseKeeper>().As<IHorseKeeper>();
builder.RegisterGeneratedFactory<AppleFactory>();
Run Code Online (Sandbox Code Playgroud)
我不太清楚如何实现方法IHorseKeeper.Feed.这是我现在拥有的:
class HorseKeeper …Run Code Online (Sandbox Code Playgroud) 我正在寻找一种如何以编程方式创建本地用户组的方法.我发现了大量关于如何查询和添加用户的示例,但我无法理解如何创建新组.
var dirEntry = new DirectoryEntry(
"WinNT://" + Environment.MachineName + ",computer");
/* Code to test if the group already exists */
if (!found)
{
DirectoryEntry grp = dirEntry.Children.Add(groupName, "Group");
dirEntry.CommitChanges();
}
Run Code Online (Sandbox Code Playgroud)
这就是我所得到的,但我知道这是错误的,CommitChanges()只是抛出一个NotImplementedException.
我一直在使用它作为样本,但我甚至无法让它工作(感谢MS):
http://msdn.microsoft.com/en-us/library/ms815734
任何人都有一个我可以用来创建一个新的本地组的代码片段?
.NET框架中的ToXXXX转换方法和AsXXXX转换方法之间是否存在语义差异?
这些方法的例子是Object.ToString和Enumerable.AsEnumerable<T>.
我正在使用我的C++项目中的Ubuntu环境中的Eclipse.
我使用该itoa函数(在Visual Studio上完美运行),编译器抱怨itoa未声明.
我包括<stdio.h>,<stdlib.h>,<iostream>这于事无补.
我发现F#2.0显然不再支持公共静态字段,这使得标准的实现方式变得不可能DependencyProperty:
public static readonly FooProperty = DependencyProperty.Register(...); // in C#
Run Code Online (Sandbox Code Playgroud)
我不太喜欢F#的一个建议解决方法,它涉及将DependencyPropertya 声明为a static mutable val然后用static do... 初始化它(或者不管它究竟是什么).
我已经尝试将一个DependencyProperty公共静态属性公开,而不是公共静态字段,这似乎在WPF应用程序中工作得很好(我已经在属性上尝试了数据绑定和样式设置器,两者都成功):
type XY() =
inherit Control()
static let fooProperty =
DependencyProperty.Register("Foo", typeof<string>, typeof<XY>)
static member public FooProperty with get () = fooProperty // see update below:
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // not required!
member public this.Foo with get (): string = this.GetValue(fooProperty) :?> string
and set (x: string) = …Run Code Online (Sandbox Code Playgroud) 我从使用StreamReader的Web服务器得到响应...现在我想解析这个响应(它是一个XML文档文件)来获取它的值,但每次我尝试这样做时都会收到一个错误:缺少根元素.
如果我直接读取相同的XML文件,文件格式正确,我可以读取它.
这是流:
WebResponse response = webRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);
string responseString = responseReader.ReadToEnd();
Run Code Online (Sandbox Code Playgroud)
这就是我尝试读取XML文件的方式:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(responseReader);
XmlNodeList address = xmlDoc.GetElementsByTagName("original");
Run Code Online (Sandbox Code Playgroud) 首先请注意,此问题未标记为winforms或wpf或其他任何GUI特定的.这是故意的,你很快就会看到.
第二,对不起,如果这个问题有点长.我尝试将各种各样的信息汇集在一起,以便提供有价值的信息.然而,我的问题正好在"我想知道的事情"之下.
我的任务是最终了解.NET提供的在特定线程上调用委托的各种方法.
我正在寻找最通用的方法(不是Winforms或WPF特定的)来调用特定线程上的委托.
或者,换句话说:我会感兴趣的是,以及如何做各种各样的方式(例如通过WPF Dispatcher)相互利用; 也就是说,如果所有其他人都使用了一种用于跨线程委托调用的通用机制.
有很多与此主题相关的课程; 其中:
SynchronizationContext (in System.Threading)
如果我不得不猜测,那将是最基本的一个; 虽然我不明白它到底是做什么,也不知道它是如何使用的.
AsyncOperation&(in )
这些似乎是包装.不知道如何使用它们.AsyncOperationManager System.ComponentModelSynchronizationContext
WindowsFormsSynchronizationContext (in System.Windows.Forms)
的子类SynchronizationContext.
ISynchronizeInvoke (in System.ComponentModel)
由Windows窗体使用.(Control该类实现了这个.如果我不得不猜测,我会说这个实现可以使用WindowsFormsSynchronizationContext.)
Dispatcher&(in )
似乎后者是另一个子类,前者代表它.DispatcherSynchronizationContext System.Windows.ThreadingSynchronizationContext
有些线程有自己的消息循环,还有消息队列.
(MSDN页面关于消息和消息队列有一些介绍消息循环如何在系统级工作的背景信息,即消息队列作为Windows API.)
我可以看到如何为具有消息队列的线程实现跨线程调用.使用Windows API,您可以将消息放入特定线程的消息队列PostThreadMessage,其中包含调用某个委托的指令.消息循环 - 在该线程上运行 - 最终将到达该消息,并且将调用该委托.
根据我在MSDN上阅读的内容,线程不会自动拥有自己的消息队列.消息队列将变为可用,例如当线程创建窗口时.没有消息队列,线程没有消息循环是没有意义的.
那么,当目标线程没有消息循环时,是否可以进行跨线程委托调用?比方说,在.NET控制台应用程序中?(从这个问题的答案来看,我认为控制台应用确实不可能.)
.net winapi multithreading system.componentmodel synchronizationcontext
如何有效地将一个输入字符串与任意数量的正则表达式匹配?
这可能有用的一个场景是REST Web服务.让我们假设我已经为REST Web服务的公共接口提出了许多URL模式:
/user/with-id/{userId}/user/with-id/{userId}/profile/user/with-id/{userId}/preferences/users/users/who-signed-up-on/{date}/users/who-signed-up-between/{fromDate}/and/{toDate}哪里{…}是命名占位符(如正则表达式捕获组).
注意:这个问题不是关于上面的REST接口是否设计得很好.(可能不是,但在这个问题的背景下,这应该不重要.)
可以假设占位符通常不会出现在模式的最开头(但它们可以).还可以安全地假设任何字符串都不可能匹配多个模式.
现在,Web服务收到请求.当然,可以将请求的URI与一个URL模式顺序匹配,然后与下一个模式匹配,依此类推; 但是,对于必须检查的大量模式,这可能无法很好地扩展.
这有什么有效的算法吗?
输入:
输出:
我正在尝试自定义Windows窗体设计器的代码生成InitializeComponent.MSDN文章"在.NET Framework可视化设计器中自定义代码生成"包含"控制代码生成"部分,该部分解释了如何执行此操作的基础知识.
我在上面的文章中密切关注了一个例子:
//using System.ComponentModel.Design.Serialization;
class SomeFormSerializer : CodeDomSerializer
{
public override object Serialize(IDesignerSerializationManager manager,
object value)
{
// first, let the default serializer do its work:
var baseSerializer = (CodeDomSerializer)manager.GetSerializer(
typeof(Form).BaseType, typeof(CodeDomSerializer));
object codeObject = baseSerializer.Serialize(manager, value);
// then, modify the generated CodeDOM -- add a comment as the 1st line:
if (codeObject is CodeStatementCollection)
{
var statements = (CodeStatementCollection)codeObject;
statements.Insert(0, new CodeCommentStatement("CODEDOM WAS HERE"));
}
// finally, return the modified CodeDOM:
return …Run Code Online (Sandbox Code Playgroud) .net ×4
c# ×4
autofac ×1
c++ ×1
designer ×1
dispose ×1
f# ×1
idisposable ×1
itoa ×1
local ×1
portability ×1
regex ×1
reliability ×1
rest ×1
stream ×1
streamreader ×1
usergroups ×1
winapi ×1
winforms ×1
wpf ×1
xml ×1