更新 - 此问题的上下文是预先TypeScript 1.4.从那个版本开始,我的第一个猜测得到了语言的支持.请参阅答案的更新.
我可以声明f
是一个接受字符串并返回字符串的函数:
var f : (string) => string
Run Code Online (Sandbox Code Playgroud)
我可以声明g
是一个字符串数组:
var g : string[]
Run Code Online (Sandbox Code Playgroud)
如何声明h
为"接受字符串并返回字符串的函数"的数组?
我的第一个猜测:
var h : ((string) => string)[]
Run Code Online (Sandbox Code Playgroud)
这似乎是一个语法错误.如果我拿掉额外的括号,那么它是一个从字符串到字符串数组的函数.
.NET中的事件有一个标准模式 - 它们使用一个delegate
类型,它接受一个名为sender的普通对象,然后是第二个参数中的实际"payload",它应该从中派生出来EventArgs
.
派生的第二个参数的基本原理EventArgs
似乎非常清楚(请参阅.NET Framework标准库带注释的参考).它旨在确保随着软件的发展,事件接收器和源之间的二进制兼容性.对于每个事件,即使它只有一个参数,我们派生一个自定义事件参数类,它具有包含该参数的单个属性,这样我们就可以保留在未来版本中向有效负载添加更多属性而不破坏现有客户端代码的能力. .在独立开发组件的生态系统中非常重要.
但我发现零参数也是如此.这意味着如果我的第一个版本中有一个没有参数的事件,我会写:
public event EventHandler Click;
Run Code Online (Sandbox Code Playgroud)
......然后我做错了.如果我将来的委托类型更改为新的类作为其有效负载:
public class ClickEventArgs : EventArgs { ...
Run Code Online (Sandbox Code Playgroud)
...我将破坏与客户的二进制兼容性.客户端上界到内部方法的具体超载add_Click
是需要EventHandler
的,如果我改变了委托类型,然后他们无法找到超载,所以有一个MissingMethodException
.
好的,那么如果我使用方便的通用版本怎么办?
public EventHandler<EventArgs> Click;
Run Code Online (Sandbox Code Playgroud)
不,仍然是错的,因为一个EventHandler<ClickEventArgs>
不是EventHandler<EventArgs>
.
因此,为了获得好处EventArgs
,您必须从中获取,而不是直接使用它.如果你不这样做,你也可以不使用它(在我看来).
然后是第一个论点,sender
.在我看来,这似乎是一个邪恶的耦合配方.事件触发本质上是一个函数调用.一般来说,这个函数是否应该能够通过堆栈挖掘并找出调用者是谁,并相应地调整其行为?我们应该强制要求接口看起来像这样吗?
public interface IFoo
{
void Bar(object caller, int actualArg1, ...);
}
Run Code Online (Sandbox Code Playgroud)
毕竟,实现者Bar
可能想知道是谁caller
,所以他们可以查询更多信息!我希望你现在正在呕吐.为什么事件会有所不同?
因此,即使我已经准备好为EventArgs
我声明的每个事件都要为一个独立的派生类而烦恼,只是为了让它值得我在使用EventArgs
时,我绝对宁愿删除对象发送者参数.
Visual Studio的自动完成功能似乎并不关心您用于事件的委托 - 您可以键入+=
[命中空间,返回]并为您编写一个匹配任何委托的处理程序方法.
那么偏离标准模式我会失去什么价值? …
更新 - 对于一个有思想的心态,你可以假设Aggregate仍会产生正常的结果,无论函数传递给它,包括在优化的情况下.
我编写了这个程序来构建一个从逗号分隔的0到19999之间的长整数字符串.
using System;
using System.Linq;
using System.Diagnostics;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
const int size = 20000;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Enumerable.Range(0, size).Select(n => n.ToString()).Aggregate((a, b) => a + ", " + b);
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds + "ms");
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它说:
5116ms
Run Code Online (Sandbox Code Playgroud)
超过五秒钟,太可怕了.当然这是因为每次循环都会复制整个字符串.
但是,如果评论中指出了一个非常小的变化呢?
using System;
using System.Linq;
using System.Diagnostics;
namespace ConsoleApplication5
{
using MakeAggregateGoFaster; // <---- inserted this
class Program
{
static void Main(string[] args)
{
const int …
Run Code Online (Sandbox Code Playgroud) 鉴于这个神奇的界面:
public interface IHat<out TRabbit>
{
TRabbit Take();
}
Run Code Online (Sandbox Code Playgroud)
而这个类层次结构:
public class Rabbit { }
public class WhiteRabbit : Rabbit { }
Run Code Online (Sandbox Code Playgroud)
我现在可以编译这个:
IHat<WhiteRabbit> hat1 = null;
IHat<Rabbit> hat2 = hat1;
Run Code Online (Sandbox Code Playgroud)
哪个好.但是如果我以不同的方式定义界面呢:
public interface IHat<out TRabbit>
{
bool Take(out TRabbit r);
}
Run Code Online (Sandbox Code Playgroud)
我指出帽子可能是空的,使用单独的布尔返回值(之前的版本可能会从空帽子返回一个空兔子).但我仍然只输出一只兔子,所以没有做任何与以前版本逻辑上不同的事情.
CTP中的C#4.0编译器在接口定义中给出了错误 - 它要求'out'方法参数为不变类型.是否有一个强硬的原因,为什么不允许这样做,或者是否可以在未来版本中解决这个问题?
Java世界有一个关于门户和portlet如何互操作的JSR-286标准:共享统一网页的软件组件.
似乎有许多门户实现.但是,是否存在可互换的portlet的实时"市场"?从我可以找到的搜索网络,它看起来非常不平衡 - 所有门户网站和没有portlet.这就像是有几十部Android手机而没有应用程序.
如果产品基于JSR-286(或其某些实现),那么企业客户有可能想要添加到门户网站的一堆portlet的可能性是多少?
令我感到震惊的是,大多数企业已经拥有一个类似门户网站的页面,这些页面基于他们选择的业务运行的ERP或CRM产品,甚至可能只是MS Outlook的"今日"页面.因此,如果我发布一个面向企业客户的新产品,并将其设为门户网站(而不是一组portlet),那么我的客户放弃现有IBM/SAP/Oracle门户网站并将我的门户网站用作新主页的可能性是多少?(我猜:不是很好.)如果我将它设置为一组兼容JSR-286的portlet,我的客户是否会有办法托管主机portlet?(我猜:也不好).
最后,JSR-286似乎对HTML + JavaScript非常无声,即门户和portlet如何在浏览器内互操作.这都是关于基于Java的服务器端的东西,定义了一种合作使用URL的方法,这样每个整页刷新都可以路由到正确的portlet.它似乎并不承认现代,丰富的AJAX方法.它只是顺便提到了AJAX.
这篇博客文章(及其下的评论)提供了许多思考的东西,似乎证实了我的怀疑:
专业的实践经验以及上述研究使我得出结论,门户架构缺乏足够的技术优势和区别特征,需要增加接受度.实际上,很少有应用程序可以将自己限制在portlet的孤立和完全不同的功能中,放弃这种程度的架构控制在企业级软件中是不现实的 ......门户架构成为主流技术的机会之窗不仅关闭了,但很久以前关闭了.
所以总结一下这是一个更连贯的问题:在这一点上我将通过构建JSR-286获得什么实际价值?
假设我想这样做,所以我可以找到鼠标相对于a的当前位置Visual
,而无需访问特定的鼠标事件:
public static Point GetMousePosition(this Visual relativeTo)
{
return relativeTo.PointFromScreen(GetMousePositionOnScreen());
}
Run Code Online (Sandbox Code Playgroud)
有时(通常当我刚刚在两个选项卡控件之间切换时)PointFromScreen
会抛出一条InvalidOperationException
消息:此Visual未连接到PresentationSource.
在查看可用的属性时,Visual
我看不到与a有关的任何内容PresentationSource
.
给定a Visual
,当我调用PointFromScreen
它时,如何判断它是否会抛出该异常?
After 3 years working as an IT Support Technician, I decided to change of field and get to Programming.
I am learning C# through the Wrox Beginning Visual C# 2008 book, that I use as guideline.
I have read the whole POO part (inheritance, Polymorphism,....delegates,...). I have started the second part which is Windows Programming (Winforms)
我知道很多人建议做一些有用的应用程序来练习,但是如果我还没有开始像SQL Server,LINQ或网络编程,WPF,WCF这样的概念,我怎么能做一些个人项目....在本书的最后给出了主题.
我只是想找到最好的方法:我应该先完成这本书,然后开始编码,或者我应该在没有阅读热门话题的情况下做一个项目,或直接跳到这些主题.
我不知道你是否明白我的意思,因为英语不是我的第一语言.但如果你不这样做,我可以改进我的解释.
我为Visual Studio 2008编写了一个简单的加载项,用于打开可停靠的窗口窗格.
加载项的性质意味着理想情况下它将停靠在编辑源的位置旁边.但有时候,在某些安装中,它不会停留在停靠状态.你运行VS,你停靠我的窗格,你关闭VS,你重新启动VS,然后敲响它 - 窗格再次浮动.在某些机器上,我每次都要重新对接它.
但是在其他安装中,无论我将它永远放在哪里,它都会停靠.我原本以为它可能是Vista和XP之间的区别,但现在我有报道称它在XP上也没有出现.
从我读过的内容(以及它有时会停留的事实)我得到的印象是VS应该为我保存对接状态.但事实并非如此.而在同一VS安装上的其他插件没有这个问题.所以我必须做些什么才能改善这种状况.
我怀疑我的代码中唯一相关的部分是这样的:
public class Connect : IDTExtensibility2
{
private static DTE2 _applicationObject;
private AddIn _addInInstance;
private static CodeModelEvents _codeModelEvents;
public static DTE2 VisualStudioApplication
{
get { return _applicationObject; }
}
public static CodeModelEvents CodeModelEvents
{
get { return _codeModelEvents; }
}
public static event EventHandler SourceChanged = delegate { };
public void OnConnection(object application,
ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
}
public void OnStartupComplete(ref …
Run Code Online (Sandbox Code Playgroud) add-in visual-studio-addins docking visual-studio-2008 visual-studio
鉴于这个简单的类:
class HasBytes
{
public byte[] Bytes { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我可以通过JSON.NET使字节数组进行base-64编码:
var bytes = new HasBytes { Bytes = new byte[] { 1, 2, 3, 4 } };
var json = JsonConvert.SerializeObject(bytes);
Run Code Online (Sandbox Code Playgroud)
然后我可以用这种稍微过于复杂的方式再次阅读它:
TextReader textReader = new StringReader(json);
JsonReader jsonReader = new JsonTextReader(textReader);
var result = (HasBytes)JsonSerializer.Create(null)
.Deserialize(jsonReader, typeof(HasBytes));
Run Code Online (Sandbox Code Playgroud)
都好.但如果我先将内容jsonReader
转换为JToken
:
var jToken = JToken.ReadFrom(jsonReader);
Run Code Online (Sandbox Code Playgroud)
然后把它JsonReader
包装成一个JTokenReader
:
jsonReader = new JTokenReader(jToken);
Run Code Online (Sandbox Code Playgroud)
然后反序列化抛出异常:"预期的字节但得到字符串".
新的JsonReader不应该在逻辑上等同于原始的JsonReader吗?为什么"raw" JsonTextReader
能够将字符串视为基本的64字节数组,而JTokenReader
版本却没有?
显然,你可以在TypeScript中说'export import xx = module("xx")'.
但是,这是什么意思?我在规范中没有看到.