我需要为现有代码添加一些扩展点,我一直在将MEF作为可能的解决方案.我们有一个IRandomNumberGenerator接口,我们希望可以交换默认实现(ConcreteRNG).这听起来像MEF的理想情况,但我一直遇到实例化随机数生成器的问题.我们当前的代码如下:
public class Consumer
{
private List<IRandomNumberGenerator> generators;
private List<double> seeds;
public Consumer()
{
generators = new List<IRandomNumberGenerator>();
seeds = new List<double>(new[] {1.0, 2.0, 3.0});
foreach(var seed in seeds)
{
generators.Add(new ConcreteRNG(seed));
}
}
}
Run Code Online (Sandbox Code Playgroud)
换句话说,消费者负责实例化其所需的RNG,包括提供每个实例所需的种子.
我想做的是让MEF发现并实例化具体的RNG实现(使用DirectoryCatalog).我不知道如何实现这一目标.我可以公开Generators属性并将其标记为[Import],但是如何提供所需的种子?
我还缺少一些其他方法吗?
关于支持.NET中的非可空引用类型,存在许多问题.最大的希望是代码合同,但它仅限于运行时检查那些预算有限的人.
至于Code Contracts之外的其他方法,Jon Skeet 几年前写了一篇关于此的博客文章,其中一位评论者提供了一个有用的NonNull结构,修改了IL以禁用默认构造函数.这似乎是一种很好的方法,我可以想象扩展它以提供各种不可空的微型.IL操作可以是由结构上的属性触发的构建后步骤,例如
//Microtype representing a non-zero age, so we want to disable the default ctor
[NoDefaultConstructor]
public struct Age
{
public Age(int age)
{
// Implementation (including validation) elided
}
}
Run Code Online (Sandbox Code Playgroud)
在我进一步调查之前,我想问一下是否有人知道这可能导致的任何问题?我一直没能想到.
使用NUnit 2.5.9,以下测试意外失败:
[TestFixture]
public class FooTest
{
[Test]
public void Inequality()
{
var first = new Foo(new[] { 1 }, 2);
var second = new Foo(new[] { 1 }, 3);
Assert.AreNotEqual(first, second);
}
}
public struct Foo : IEnumerable<int>, IEquatable<Foo>
{
private readonly IEnumerable<int> values;
public int Bar { get; private set; }
public Foo(IEnumerable<int> values, int bar)
: this()
{
this.values = values;
Bar = bar;
}
public IEnumerator<int> GetEnumerator()
{
return values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator(); …Run Code Online (Sandbox Code Playgroud) 使用Task <T>时,在Task.Wait()期间抛出任务执行期间的异常; 当使用F#的MailBoxProcessor时,异常会被吞下,需要根据这个问题明确处理.
这种差异使得很难通过Task将F#代理暴露给C#代码.例如,此代理:
type internal IncrementMessage =
Increment of int * AsyncReplyChannel<int>
type IncrementAgent() =
let counter = Agent.Start(fun agent ->
let rec loop() = async { let! Increment(msg, replyChannel) = agent.Receive()
match msg with
| int.MaxValue -> return! failwith "Boom!"
| _ as i -> replyChannel.Reply (i + 1)
return! loop() }
loop())
member x.PostAndAsyncReply i =
Async.StartAsTask (counter.PostAndAsyncReply (fun channel -> Increment(i, channel)))
Run Code Online (Sandbox Code Playgroud)
可以从C#调用,但异常不会返回给C#:
[Test]
public void ExceptionHandling()
{
//
// TPL exception behaviour
// …Run Code Online (Sandbox Code Playgroud) 首先,为糟糕的头衔道歉 - 我不太了解F#来更好地描述问题.
考虑这个简单的DU:
type Money =
| USD of decimal
| GBP of decimal
| EUR of decimal
static member (+) (first: Money, second: Money) =
match first, second with
| USD(x), USD(y) -> USD(x + y)
| GBP(x), GBP(y) -> GBP(x + y)
| EUR(x), EUR(y) -> EUR(x + y)
| _ -> failwith "Different currencies"
Run Code Online (Sandbox Code Playgroud)
我用不同的货币代表货币,并超载(+)运营商,以便我可以安全地做Money + Money.但是,如果我有很多货币,那么匹配声明将变得乏味.有没有办法表达如下:
match first, second with
| _(x), _(y) -> _(x + y)
Run Code Online (Sandbox Code Playgroud)
或者有不同的方法来实现相同的结果?由于此处描述的限制,我已经考虑并放弃了计量单位.
地图函数(Seq.map,List.map等)是否具有隐含的后置条件,即输出与输入具有相同数量的项目?更进一步,如果我们有某种Tree.map函数,是否假设输入和输出树的"形状"是相同的?
我问的原因是我总是做出这样的假设(我怀疑很多映射在序列上的代码也会这样做),但后来我发现如果映射函数产生重复,Set.map可以返回一个较小的集合. .因此,我的假设无效,或者Set不应被视为用于映射目的的序列.这是什么?
我有一个使用SQLite进行存储的应用程序,我想知道使用Windows DFS复制将数据库文件备份到安装了该应用程序的冷备用实例的第二台服务器是否安全。
可能相关的详细信息:
如果DFS在复制期间锁定了主数据库文件,那么我认为只要锁定的保持时间不长,这种方法就可以起作用。但是,我找不到有关如何实现DFS的足够信息。
更新:我已经在测试环境中实现了它,并且已经运行了好几天。在那段时间内我没有遇到任何问题,因此我很想采用这种解决方案。
sqlite microsoft-distributed-file-system database-replication
我有一个ReSTful Web服务,需要解析请求中的区域设置敏感数据.此数据可以位于XML正文中,也可以位于查询字符串的一部分中.是否有任何通过哪种方法来确定发送数据的区域设置(以及扩展应该发送响应的区域设置)?
一种选择是简单地向客户端指定应该发送所有请求的语言环境.更友好的选择似乎是允许客户端指定语言环境.
我考虑过:
a)使用accept-language http头来编码这些信息.
b)对XML POST使用xml:lang属性,为查询字符串使用额外字段(例如......&locale = en-GB)
http://www.w3.org/International/questions/qa-accept-lang-locales警告使用接受语言标头的限制,但大多数警告似乎都集中在源自浏览器的请求.在我的情况下,请求将来自其他应用程序.
所有建议都非常感谢!
假设我在F#中定义了以下接口:
type IFoo<'T> =
abstract member DoStuff : 'T -> unit
Run Code Online (Sandbox Code Playgroud)
如果我在C#中实现这一点,则需要方法签名为:
public void DoStuff<T>(T arg) {...}
Run Code Online (Sandbox Code Playgroud)
我真正想做的是引用FSharp.Core,然后使用:
public Unit DoStuff<T>(T arg) {...}
Run Code Online (Sandbox Code Playgroud)
这将简化其他代码,因为我不必处理Action vs Func。我猜测没有任何干净的方法可以实现这一目标?邪恶的骇客怎么样?
假设我有以下DU:
type Something =
| A of int
| B of string * int
Run Code Online (Sandbox Code Playgroud)
现在我在这样的函数中使用它:
let UseSomething = function
| A(i) -> DoSomethingWithA i
| B(s, i) -> DoSomethingWithB s i
Run Code Online (Sandbox Code Playgroud)
这是有效的,但我必须解构DU才能将它传递给DoSomethingWith*函数.尝试将DoSomethingWithA定义为:我觉得很自然:
let DoSomethingWithA (a: Something.A) = ....
Run Code Online (Sandbox Code Playgroud)
但编译器抱怨未定义类型A.
似乎完全符合F#的哲学,希望将参数限制为Something.A,而不仅仅是任何旧的int,所以我只是以错误的方式去做?
f# ×5
.net ×2
functor ×1
http-headers ×1
ienumerable ×1
locale ×1
mef ×1
microsoft-distributed-file-system ×1
non-nullable ×1
null ×1
nunit ×1
rest ×1
sqlite ×1
unit-type ×1