我正在使用Code Contracts和Code Contracts Editor Extensions VS2010加载项.我有一个实现IEnumerable<T>接口的类,我已经为该GetEnumerator()方法实现了一个迭代器块.在它上面,我可以看到以下继承的合同:
![确保结果!= null确保result.Model ==((IEnumerable)this).Model [Pure] public IEnumerator(of IBaseMessage)GetEnumerator(){](https://i.stack.imgur.com/rh39r.png)
我理解第一个和第三个合同要求 - GetEnumerator()必须永远不会返回null,并且它必须永远不会导致副作用.但第二份合同要求意味着什么?这个Model属性IEnumerator<T>是IEnumerable什么?
编辑:正如Damien_The_Unbeliever在他的评论中所指出的那样,合同IEnumerable<T>和IEnumerator<T>位于一个单独的文件,一个合同参考大会.使用Reflector,在这两个接口的合同的反汇编中(完整代码在这里),您可以看到以下内容:
[return: Fresh]
[Escapes(true, false), Pure, GlobalAccess(false)]
public IEnumerator GetEnumerator()
{
IEnumerator enumerator;
Contract.Ensures((bool) (Contract.Result<IEnumerator>() != null), null, "Contract.Result<IEnumerator>() != null");
Contract.Ensures((bool) (Contract.Result<IEnumerator>().Model == this.Model), null, "Contract.Result<IEnumerator>().Model == this.Model");
Contract.Ensures((bool) (Contract.Result<IEnumerator>().CurrentIndex == -1), null, "Contract.Result<IEnumerator>().CurrentIndex == -1");
return enumerator;
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,GetEnumerator()编辑器扩展中没有显示额外的合同:
Contract.Result<IEnumerator>().CurrentIndex == -1
Run Code Online (Sandbox Code Playgroud)
而一些additionaly奥秘(如Fresh …
Async Targeting Pack的发布促使我使用ILSpy来查看那里提供了哪些基于任务的异步模式(TAP)扩展方法(其中一些我自己已经实现了在VS2010中使用).我偶然发现了这个.CancelAfter(TimeSpan)方法CancellationTokenSource(这是.NET 4.0异步目标包中的扩展方法,但它是.NET 4.5中的实例方法),并认为这可能是一种很好的方法来实现各种操作的超时.本地有超时,但支持取消.
但是看看Async Targeting Pack中的实现,似乎如果关联Task完成或取消,则计时器继续运行.
/// <summary>Cancels the <see cref="T:System.Threading.CancellationTokenSource" /> after the specified duration.</summary>
/// <param name="source">The CancellationTokenSource.</param>
/// <param name="dueTime">The due time in milliseconds for the source to be canceled.</param>
public static void CancelAfter(this CancellationTokenSource source, int dueTime)
{
if (source == null)
{
throw new NullReferenceException();
}
if (dueTime < -1)
{
throw new ArgumentOutOfRangeException("dueTime");
}
Timer timer = new Timer(delegate(object …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序,它在用户设置中存储对象集合,并通过 ClickOnce 进行部署。应用程序的下一版本对存储的对象类型进行了修改。例如,之前版本的类型是:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
新版本的类型是:
public class Person
{
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
显然,ApplicationSettingsBase.Upgrade不知道如何执行升级,因为 Age 需要使用 进行转换(age) => DateTime.Now.AddYears(-age),因此只有 Name 属性会被升级,而 DateOfBirth 将只有 Default(DateTime) 的值。
所以我想通过重写提供一个升级例程,ApplicationSettingsBase.Upgrade它将根据需要转换值。但我遇到了三个问题:
ApplicationSettingsBase.GetPreviousVersion,返回的值将是当前版本的对象,该对象没有 Age 属性并且具有空的 DateOfBirth 属性(因为它无法将 Age 反序列化为 DateOfBirth)。我正在反思一个类型的属性,并想检查一个属性是否同时具有公共 setter和getter.不幸的是,PropertyInfo的CanRead和CanWrite不表示可进入等级.所以我转向PropertyInfo.GetAccessors()有一个有趣的描述(强调我的):
返回一个数组,其元素反映当前实例反映的属性的公共get,set和其他访问器.
还有什么"其他配件"?是否存在其他访问者的可能性,或者是否存在实际上比属性的简单set/get duo更多的CLI语言?
我有一个方法:
void MyMethod<T>(params Func<T>[] funcs) { }
Run Code Online (Sandbox Code Playgroud)
我想用异步lambdas调用它:
MyMethod(async () => 1, async () => 2, async () => 3);
Run Code Online (Sandbox Code Playgroud)
有用!但是如果我想让第三个lambda抛出异常呢?
MyMethod(async () => 1, async () => 2, async () => { throw new Exception(); });
Run Code Online (Sandbox Code Playgroud)
上面没有编译,它给出了两个相同的错误:
CS0201只能将赋值,调用,递增,递减和新对象表达式用作语句
我不确定它为什么会出现这个错误,但我理解为什么它无法编译 - 前两个lambdas是Func<Task<int>>最后一个Func<Task>.我希望它能给我一个更好的编译错误,但让我们把这个问题放在一边.
如何编译代码?我可能不得不告诉编译器我想为第三个异步lambda生成什么类型的任务.我找到的一种方法是在return语句后指定一个throw语句:
MyMethod(async () => 1, async () => 2, async () => { throw new Exception(); return 3; });
Run Code Online (Sandbox Code Playgroud)
除了丑陋和令人困惑之外,它还会生成编译器警告:
CS0162检测到无法访问的代码
如何让编译器满意?如何避免无法访问的代码才能使其编译?是否有另一种方法来指定异步lambda返回的任务类型?
另外,为什么我在上面的例子中遇到CS0201错误?
在回答之前:这个问题是关于WPF的ListView控制(带GridView).它不是关于WPF的DataGrid控件,ASP.NET DataGrid或ListView控件,或WinForm DataGridView或ListView控件.它们听起来非常相似并经常混淆,但错误控制类型的答案对我来说无益,更重要的是浪费你写答案的时间,我认为不应该浪费.
我有一个ListView控件GridView,有几列绑定到我的视图模型的属性.我可以GridViewColumn通过指定CellTemplate(内联或通过资源)轻松自定义单元格的视觉外观.
现在我的视图模型上有一个特定的属性; 它的类型是一个抽象基类,它的值可以是几种派生类型之一.每个派生类型DataTemplate在单元格中应该有不同的类型.幸运的是,GridViewColumn有一个CellTemplateSelector完全符合我的要求,但需要编写一些管道代码.但是看一下DataTemplateSelector它的页面说:
请注意,如果您有不同类型的对象,则可以在DataTemplate上设置DataType属性.如果这样做,则无需创建DataTemplateSelector.[...]有关更多信息,请参阅数据模板概述.
欢呼!无需编写管道代码.我的类型是不同的,因此这似乎是一个完美的结合.但是,即使在我定义了DataTemplate一个DataType匹配数据绑定列之一(使用GridViewColumn's 绑定)的特定派生类型之后DisplayMemberBinding,它也没有效果.
我只想DataTemplate根据我的某个列的运行时类型显示不同的GridView.是DataType靶向性DataTemplates根本不兼容GridView?有没有办法使用它们,还是我必须指定一个CellTemplateSelector?或许有指定多个方式DataTemplate在s GridViewColumn的CellTemplate,这样DataType属性将产生效果?
这段代码有什么问题?我一直在StackOverlflowException......
public class Places
{
public string Title { get; set; }
public string Content { get; set; }
public double Latitude { get; set; }
public double Longtitude { get; set; }
public List<Places> allPlaces = new List<Places>
{
new Places { Title = "test", Content = "test\ntest", Latitude = 52.23057, Longtitude = 5.84582 },
new Places { Title = "testt", Content = "dfsdf", Longtitude = 52.35589, Latitude = 4.92119 }
};
}
Run Code Online (Sandbox Code Playgroud) c# ×6
.net ×4
.net-4.0 ×1
.net-4.5 ×1
async-await ×1
c#-5.0 ×1
class ×1
clickonce ×1
clr ×1
datatemplate ×1
ienumerable ×1
lambda ×1
list ×1
wpf ×1
xaml ×1