小编Pav*_*aev的帖子

.NET中API破坏性更改的权威指南

我想尽可能多地收集有关.NET/CLR中API版本控制的信息,特别是API更改如何破坏客户端应用程序.首先,让我们定义一些术语:

API更改 - 类型的公开可见定义的更改,包括其任何公共成员.这包括更改类型和成员名称,更改类型的基本类型,从类型的已实现接口列表添加/删除接口,添加/删除成员(包括重载),更改成员可见性,重命名方法和类型参数,添加默认值对于方法参数,在类型和成员上添加/删除属性,以及在类型和成员上添加/删除泛型类型参数(我错过了什么吗?).这不包括成员团体的任何变化,或私人成员的任何变化(即我们不考虑反射).

二进制级别中断 - 一种API更改,导致针对旧版本API编译的客户端程序集可能无法加载新版本.示例:更改方法签名,即使它允许以与之前相同的方式调用(即:void返回类型/参数默认值重载).

源级别中断 - 一种API更改,导致编写现有代码以针对旧版本的API进行编译,可能无法使用新版本进行编译.然而,已经编译的客户端程序集像以前一样工作.示例:添加一个新的重载,这可能导致前一个明确的方法调用不明确.

源级安静语义更改 - 一种API更改导致编写的现有代码针对旧版API进行编译,从而悄然改变其语义,例如通过调用不同的方法.但是,代码应该继续编译而不会出现警告/错误,以前编译的程序集应该像以前一样工作.示例:在现有类上实现新接口,导致在重载解析期间选择不同的重载.

最终目标是尽可能地对尽可能多的破坏和静默语义API更改进行编目,并描述破坏的确切影响,以及哪些语言受其影响并且不受其影响.扩展后者:虽然一些变化普遍影响所有语言(例如,向接口添加新成员将破坏任何语言中该接口的实现),但有些需要非常特定的语言语义才能进入游戏以获得休息.这通常涉及方法重载,并且通常涉及与隐式类型转换有关的任何事情.似乎没有任何方法可以在这里定义"最小公分母",即使对于符合CLS的语言(即至少符合CLI规范中定义的"CLS使用者"规则的那些语言) - 尽管我会很感激,如果有人在这里纠正我错了 - 所以这必须按语言去语言.那些最感兴趣的东西自然就是开箱即用的.NET:C#,VB和F#; 但其他人,如IronPython,IronRuby,Delphi Prism等也是相关的.它的角落越多,它就越有趣 - 删除成员之类的东西是不言而喻的,但是例如方法重载,可选/默认参数,lambda类型推断和转换运算符之间的微妙交互可能会非常令人惊讶有时.

举几个例子来启动这个:

添加新方法重载

种类:源级休息

受影响的语言:C#,VB,F#

更改前的API:

public class Foo
{
    public void Bar(IEnumerable x);
}
Run Code Online (Sandbox Code Playgroud)

更改后的API:

public class Foo
{
    public void Bar(IEnumerable x);
    public void Bar(ICloneable x);
}
Run Code Online (Sandbox Code Playgroud)

示例客户端代码在更改之前工作并在其之后中断:

new Foo().Bar(new int[0]);
Run Code Online (Sandbox Code Playgroud)

添加新的隐式转换运算符重载

种类:源级休息.

受影响的语言:C#,VB

语言不受影响:F#

更改前的API:

public class Foo
{
    public static implicit operator int ();
}
Run Code Online (Sandbox Code Playgroud)

更改后的API:

public class Foo
{
    public static implicit operator int …
Run Code Online (Sandbox Code Playgroud)

.net versioning api clr cls-compliant

219
推荐指数
10
解决办法
3万
查看次数

Python有匿名类吗?

我想知道Python是否有类似C#匿名类的功能.为了澄清,这是一个示例C#片段:

var foo = new { x = 1, y = 2 };
var bar = new { y = 2, x = 1 };
foo.Equals(bar); // "true"
Run Code Online (Sandbox Code Playgroud)

在Python中,我会想象这样的事情:

foo = record(x = 1, y = 2)
bar = record(y = 2, x = 1)
foo == bar  # true
Run Code Online (Sandbox Code Playgroud)

具体要求是能够在表达式上下文中创建具有指定字段的对象(例如,在lambda和其他不允许语句的地方可用),没有额外的外部声明,并且能够通过普通成员按名称访问各个组件访问语法foo.bar.创建的对象还应该按组件名称 (而不是按位置,如元组那样)实现结构比较.

特别是:元组不是因为它们的组件没有命名; 课程不是因为它们需要声明; dicts不是因为他们有不受欢迎的foo["bar"]语法来访问组件.

namedtuple不是它,因为即使你定义内联类型它仍然需要一个名称,并且比较是基于位置的,而不是基于名称的.特别是:

 def foo(): return namedtuple("Foo", "x y")(x = 1, y = 2)
 def bar(): return namedtuple("Foo", "y x")(x = …
Run Code Online (Sandbox Code Playgroud)

python

66
推荐指数
6
解决办法
4万
查看次数

可以在Visual Studio中使用Python工具吗?

我正在与一些同学合作构建一个python应用程序,并希望使用Visual Studio智能感的"训练轮".他们在mac和linux上使用python,所以理想情况下我们的源代码控制仓库将只包含*.py我们编写的源文件和requirements.txtpip dependancies 的导出(使用该pip freeze方法).

我希望能够创建一个新的Visual Studio项目,然后能够在该项目中运行以下命令(例如):

pip install boto
pip install fabric
pip install cuisine
pip freeze > requirements.txt
Run Code Online (Sandbox Code Playgroud)

之后,能够编写一些引用这些库的代码,并能够在Visual Studio中运行它.

有没有办法做到这一点?Visual Studio中的Python是否能够以pip中可用的格式处理模块,或者VS中使用的所有python库是否都必须针对Windows进行预编译?

在此先感谢您的帮助!

python pip visual-studio ptvs

52
推荐指数
5
解决办法
7万
查看次数

C#4表达式树中的"动态"

我正在试图弄清楚如何将所有部分组合在一起,并希望从一个简单的案例开始的具体源代码示例.

考虑以下C#代码:

Func<int, int, int> f = (x, y) => x + y;
Run Code Online (Sandbox Code Playgroud)

我可以使用表达式树在运行时生成等效函数,如下所示:

var x = Expression.Parameter(typeof(int), "x");
var y = Expression.Parameter(typeof(int), "y");
Func<int, int, int> f =
    Expression.Lambda<Func<int, int, int>>(
        Expression.Add(x, y),
        new[] { x, y }
    ).Compile();
Run Code Online (Sandbox Code Playgroud)

现在给出以下lambda:

Func<dynamic, dynamic, dynamic> f = (x, y) => x + y;
Run Code Online (Sandbox Code Playgroud)

如何使用表达式树(并且,大概Expression.Dynamic)生成等效的?

c# dynamic expression-trees c#-4.0

49
推荐指数
1
解决办法
1万
查看次数

Windows 8,C++和Metro GUI示例?

所以我看看这个Windows构建主题演讲 (Windows构建主题演讲1:42:56)我只是不明白 - 我可以用什么来创建能够从我的C++代码调用函数的C++和/或GUI语言的GUI?HTML,XAML还是什么?在哪里可以看到使用C++ for Windows 8 Metro应用程序执行markup call codecode create GUI示例的代码示例?

c++ windows user-interface windows-8 windows-runtime

24
推荐指数
3
解决办法
2万
查看次数

多重继承运算符的重载分辨率()

首先,考虑一下这个C++代码:

#include <stdio.h>

struct foo_int {
    void print(int x) {
        printf("int %d\n", x);
    }    
};

struct foo_str {
    void print(const char* x) {
        printf("str %s\n", x);
    }    
};

struct foo : foo_int, foo_str {
    //using foo_int::print;
    //using foo_str::print;
};

int main() {
    foo f;
    f.print(123);
    f.print("abc");
}
Run Code Online (Sandbox Code Playgroud)

正如根据标准所预期的那样,这无法编译,因为print为了重载解析的目的在每个基类中单独考虑,因此调用是不明确的.这是Clang(4.0),gcc(6.3)和MSVC(17.0)的情况 - 请参阅此处的 godbolt结果.

现在考虑以下片段,唯一的区别是我们使用operator()而不是print:

#include <stdio.h>

struct foo_int {
    void operator() (int x) {
        printf("int %d\n", x);
    }    
};

struct foo_str {
    void operator() (const …
Run Code Online (Sandbox Code Playgroud)

c++ lambda multiple-inheritance language-lawyer overload-resolution

24
推荐指数
1
解决办法
645
查看次数

C++ 0x lambdas编码风格

我想知道人们在编码风格方面是如何使用C++ 0x lambdas的.最有趣的问题是编写捕获列表时有多彻底.一方面,语言允许明确地列出捕获的变量,并且通过"显式优于隐式规则",因此有必要进行详尽的列表以清楚地说明意图.例如:

 int sum;
 std::for_each(xs.begin(), xs.end(), [&sum](int x) { sum += x });
Run Code Online (Sandbox Code Playgroud)

对此的另一个论点是,由于ref-captured本地的生命周期不会因为它们被捕获而改变(因此lambda很容易最终引用其生命周期已经结束的本地),因此使捕获显式有助于减少此类错误并追踪他们.

另一方面,该语言还故意提供了自动捕获所有引用的本地语言的快捷方式,因此很明显它是打算使用的.并且可以声称,对于上面的一个示例,即使使用自动捕获也会非常清楚会发生什么,并且lambda的生命周期不会超出周围的范围,因此没有理由不使用它:

 int sum;
 std::for_each(xs.begin(), xs.end(), [&](int x) { sum += x });
Run Code Online (Sandbox Code Playgroud)

显然,这不一定是全有或全无,但必须有一些理由来决定何时自动捕获,以及何时明确捕获.有什么想法吗?

同样的另一个问题是何时使用逐个拷贝 - [=]以及何时使用按引用捕获 - [&].捕获通过复制显然是安全的,因为没有寿命的问题,所以人们可以说,它应该是默认何时使用,没有必要变异捕捉值(或看到其他地方做了一些修改),并且捕获-在这种情况下,副引用应被视为(可能过早地)优化,仅在明显有所作为的情况下应用.

在另一方面,捕获按引用总是会更快(特别是因为它常常可以优化向下到复制,如果是后者实际上是更快的,对于小的类型和inlineable模板函数如最STL算法),以及是如果lambda永远不会超出其范围(这也适用于所有STL算法),那么安全性是非常安全的,因此在这种情况下默认为引用捕获是一种无关紧要且无害的优化.

你的想法是什么?

c++ lambda coding-style c++11

22
推荐指数
2
解决办法
3709
查看次数

Thread.join的行为与我在scala中的预期不同

在下面的代码中,我创建了20个线程,让它们分别打印出一条消息,睡眠并打印另一条消息.我在主线程中启动线程,然后加入所有线程.我希望只有在所有线程完成后打印"全部完成"消息.然而,在完成所有线程之前,"全部完成"被打印出来.有人可以帮我理解这种行为吗?

谢谢.肯特

这是代码:

  def ttest() = {
     val threads = 
      for (i <- 1 to 5)
        yield new Thread() {
          override def run() {
            println("going to sleep")
            Thread.sleep(1000)
            println("awake now")
          }
        }

    threads.foreach(t => t.start())
    threads.foreach(t => t.join())
    println("all done")
  }
Run Code Online (Sandbox Code Playgroud)

这是输出:

going to sleep
all done
going to sleep
going to sleep
going to sleep
going to sleep
awake now
awake now
awake now
awake now
awake now
Run Code Online (Sandbox Code Playgroud)

multithreading scala join

17
推荐指数
2
解决办法
2669
查看次数

Ruby中的任务/未来

什么是模式的惯用Ruby模拟,表示可能延期的异步计算,可以订阅它的完成?即.NET System.Threading.Task或Python 3.x中的某些东西concurrent.futures.future.

请注意,这并不一定意味着多线程 - "未来"对象的实际实现可能会使用其他方式来调度工作和获取结果,并且超出了问题的范围.该问题严格地涉及呈现给对象的用户的API.

ruby asynchronous

16
推荐指数
2
解决办法
6409
查看次数

针对已知密钥集的最快可能的字符串键查找

考虑具有以下签名的查找函数,该签名需要返回给定字符串键的整数:

int GetValue(string key) { ... }
Run Code Online (Sandbox Code Playgroud)

此外,在编写函数的源代码时,事先知道编号为N的键值映射,例如:

// N=3
{ "foo", 1 },
{ "bar", 42 },
{ "bazz", 314159 }
Run Code Online (Sandbox Code Playgroud)

因此,上述输入的函数的有效(但不完美!)实现将是:

int GetValue(string key)
{
    switch (key)
    {
         case "foo": return 1;
         case "bar": return 42;
         case "bazz": return 314159;
    }

    // Doesn't matter what we do here, control will never come to this point
    throw new Exception();
}
Run Code Online (Sandbox Code Playgroud)

事先还知道每个给定密钥在运行时调用该函数的次数(C> = 1).例如:

C["foo"] = 1;
C["bar"] = 1;
C["bazz"] = 2;
Run Code Online (Sandbox Code Playgroud)

但是,此类呼叫的顺序尚不清楚.例如,上面可以描述运行时的以下调用序列:

GetValue("foo");
GetValue("bazz");
GetValue("bar");
GetValue("bazz"); …
Run Code Online (Sandbox Code Playgroud)

hash lookup-tables perfect-hash

15
推荐指数
1
解决办法
3370
查看次数