是的,所以我有一个可枚举的,并希望从中获得不同的值.
使用System.Linq
,当然有一个名为的扩展方法Distinct
.在简单的情况下,它可以在没有参数的情况下使用,例如:
var distinctValues = myStringList.Distinct();
Run Code Online (Sandbox Code Playgroud)
好的,但如果我有一个可以指定相等性的可枚举对象,唯一可用的重载是:
var distinctValues = myCustomerList.Distinct(someEqualityComparer);
Run Code Online (Sandbox Code Playgroud)
equality comparer参数必须是.的实例IEqualityComparer<T>
.当然,我可以做到这一点,但它有点冗长,而且很有说服力.
我所期望的是一个需要lambda的重载,比如Func <T,T,bool>:
var distinctValues
= myCustomerList.Distinct((c1, c2) => c1.CustomerId == c2.CustomerId);
Run Code Online (Sandbox Code Playgroud)
任何人都知道是否存在某些此类扩展或某些等效的解决方法?或者我错过了什么?
或者,有没有一种方法可以指定IEqualityComparer内联(embarass me)?
更新
我找到了Anders Hejlsberg对MSDN论坛中关于这个主题的帖子的回复.他说:
您将遇到的问题是,当两个对象比较相等时,它们必须具有相同的GetHashCode返回值(否则Distinct内部使用的哈希表将无法正常运行).我们使用IEqualityComparer,因为它将Equals和GetHashCode的兼容实现打包到一个接口中.
我认为那是有道理的..
我正在编写几个需要共享资源和个人资源的WPF用户控件.
我已经找到了从单独的资源文件加载资源的语法:
<UserControl.Resources>
<ResourceDictionary Source="ViewResources.xaml" />
</UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)
但是,当我这样做时,我不能在本地添加资源,例如:
<UserControl.Resources>
<ResourceDictionary Source="ViewResources.xaml" />
<!-- Doesn't work: -->
<ControlTemplate x:Key="validationTemplate">
...
</ControlTemplate>
<style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
...
</style>
...
</UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)
我看过ResourceDictionary.MergedDictionaries,但这只能让我合并多个外部字典,而不是在本地定义更多资源.
我一定错过了一些微不足道的事情?
应该提到的是:我在WinForms项目中托管我的用户控件,因此在App.xaml中放置共享资源并不是一个真正的选择.
我们刚刚进入WPF中的MVVM.
我们已经使用我们在视图中绑定的"强类型"属性(int,double?等)实现了我们的ViewModel.
大多数类型转换都可以正常工作,因此输入数据非常简单.但是我们遇到验证问题.
例如,如果在绑定到数字属性的文本框中输入非数字值,则转换失败,永远不会设置该属性,并且我们永远不会有机会向用户提供正确的反馈.更糟糕的是,该属性保留其当前值,导致视图中显示的内容与ViewModel中实际显示的内容不匹配.
我知道,所有这些都可以通过价值转换器来处理.但我已经看到了一些意见,认为转换不应该是视图的责任.在视图中输入的是字符串,转换,验证等应该是ViewModel的职责(所以参数是这样).
如果是这样,我们应该将ViewModel上的大多数属性重写为字符串,并通过IErrorInfo接口提供错误信息.它肯定会在视图中使更简单,更精简的XAML.另一方面,从View设计者的角度来看,转换,验证等将不那么具有说明性,明确性和灵活性.
在我们看来,这两种方法根本不同,所以在我们决定之前,我们希望在这个问题上有一些明智的SO意见.
那么:ViewModels是否应该向视图公开一个简化的"基于文本"的界面并在内部处理转换?或者ViewModel属性是否应该公开实际的数据类型,将这些杂项留给视图来处理?
更新:
很难在这里挑选一个胜利者,但我终于找到了一个或多或少像我一样的人.
具体来说,我们决定保持键入ViewModel属性.其主要原因是它在视图设计中提供了灵活性,并且在XAML中具有显式,声明性转换/格式化的强大功能.
我注意到一个假设,你会在这方面不同意我们,视图的设计是固定的和准备好的.因此,不需要在视图中做出关于转换,格式化等的决定.但是我们的过程是一个敏捷的过程,而且我们还没有预先知道用户界面的所有细节.
事实上,在此过程中留下UI的细节留下了创造空间,而且,在我看来,即使是精心设计的设计也总是会在整个实施过程中变形.
所有这一切的重点在于,虽然业务规则实施当然属于ViewModel,但在我们看来,简单的转换和格式化是一种观点.这可能听起来像异端,但我实际上并不认为视图中的类型转换根本不需要单元测试(所以我们对实际的类型转换器进行单元测试).
总而言之,这是一个很好的讨论,伙计们,有良好的表达,知情的意见.谢谢.
正如你们中的一些人所发现的那样,一个新特性(?)出现在WPF 4中,其中数据绑定引擎可以将名为" {DisconnectedItem} " 的类MS.Internal.NamedObject的自定义控件实例传递到DataContext中 - 而不是您的代码所期望的数据项(当模板控件被其ItemsControl断开时会发生这种情况).这些被称为哨兵对象.
在现有代码中,这可能导致虚假异常,其中代码没有准备好.这些可以被数据绑定子系统吞噬,或者它们可能造成严重破坏.密切关注您的调试控制台.
无论如何,我在这个MSDN论坛上了解到了这一点.Sam Bent的帖子解释了这一切.现在去读它,你会想知道这个.实质是这些事件永远不会被解雇(这就是错误),所以:
如果DataContext是sentinel对象,则忽略DataContextChanged事件.
所以,我想检查一下我的DataContext.但是怎么样?考虑:
public bool IsSentinelObject(object dataContext)
{
return (dataContext is MS.Internal.NamedObject);
}
Run Code Online (Sandbox Code Playgroud)
猜猜会发生什么?它没有编译,因为MS.Internal.NamedObject是内部的,我无法访问.当然,我可以像这样破解它:
public bool IsSentinelObject(object dataContext)
{
return dataContext.GetType().FullName == "MS.Internal.NamedObject"
|| dataContext.ToString() == "{DisconnectedObject}";
}
Run Code Online (Sandbox Code Playgroud)
(或其他东西,有效).我也遵循Sam的建议缓存对象以供以后引用相等性检查(它是一个单例).
当然,这意味着我没有问题,不是真的.但我很好奇,这篇文章肯定会让一些用户受益,所以无论如何都值得问:
有没有办法可以根据内部NamedObject类型精确检查类型,而无需求助于字符串比较?
我知道有几个帖子已经涉及演员和as
运营商之间的区别.他们都大多重申相同的事实:
as
运营商将不会抛出,但返回null
如果转换失败as
运算符仅适用于引用类型as
操作者将不使用用户定义的转换运算符然后,答案倾向于无休止地讨论如何使用或不使用其中一个或每个的利弊,甚至是他们的表现(我根本不感兴趣).
但是这里还有更多工作要做.考虑:
static void MyGenericMethod<T>(T foo)
{
var myBar1 = foo as Bar; // compiles
var myBar2 = (Bar)foo; // does not compile ('Cannot cast expression of
// type 'T' to type 'Bar')
}
Run Code Online (Sandbox Code Playgroud)
请不要介意这个明显懊悔的例子是否是好的做法.我在这里关注的是两者之间非常有趣的差异,因为演员阵容不会编译,而不是as
.我真的想知道是否有人可以对此有所了解.
正如人们常说的那样,as
运营商忽视了用户定义的转换,但在上面的例子中,显然两者的能力更强.请注意,as
就编译器而言,类型T和Bar之间(编译时未知)之间没有已知的连接.演员阵容完全是"运行时".我们是否应该怀疑演员阵容在编译时是全部还是部分解决而as
操作员不是?
顺便说一下,添加类型约束毫不奇怪地修复了强制转换,因此:
static void MyGenericMethod<T>(T foo) where T : Bar
{
var myBar1 = foo as Bar; // compiles
var myBar2 = (Bar)foo; …
Run Code Online (Sandbox Code Playgroud) 在我的WPF项目中,我将用户控件保存在单独的库项目中.用户控件访问单独的XAML文件中的资源,如下所示:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/ViewResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- Local styles here -->
</ResourceDictionary>
</UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)
资源文件ViewResources.xaml驻留在名为Resources的控件库项目的文件夹中.它具有默认构建操作(页面)和自定义工具(MSBuild:Compile).
问题是当我在WPF应用程序中引用控件库并使用用户控件时.在运行时,我得到以下XamlParseException:
Set property 'System.Windows.ResourceDictionary.Source' threw an exception.
Run Code Online (Sandbox Code Playgroud)
...包装IOException:
Cannot locate resource 'resources/viewresources.xaml'.
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?我试图将资源文件的构建操作更改为"内容",并将其复制到输出目录(适用于文件和类似的"哑"资源).但无济于事.此外,它在用户控件中不起作用属性.
有没有更好的方法来指定路径?
我是否必须将资源文件移动到应用程序项目(我不愿意,因为它属于用户控件的域).
我正在使用OleDbConnection类从Excel 2000/2003工作簿中检索数据:
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + filename + ";" +
"Extended Properties=\"Excel 8.0;IMEX=1\";";
OleDbConnection connection = new OleDbConnection(connectionString);
connection.Open();
// code to get table name from schema omitted
var dataAdapter = new OleDbDataAdapter(string.Format("SELECT * FROM [{0}]", name),connection);
var myDataSet = new DataSet();
dataAdapter.Fill(myDataSet, "ExcelInfo");
Run Code Online (Sandbox Code Playgroud)
现在结果表明,工作表中长度大于255个字符的单元格正在被截断.这是Microsoft.Jet.OLEDB提供程序中的限制,还是我可以做些什么呢?
任何人?
我们需要存根一个泛型方法,该方法将使用匿名类型作为类型参数进行调用.考虑:
interface IProgressReporter
{
T Report<T>(T progressUpdater);
}
// Unit test arrange:
Func<object, object> returnArg = (x => x); // we wish to return the argument
_reporter.Stub(x => x.Report<object>(null).IgnoreArguments().Do(returnArg);
Run Code Online (Sandbox Code Playgroud)
如果在测试方法中对.Report <T>()的实际调用是使用object作为类型参数完成的,那么这将起作用,但实际上,调用该方法时T是匿名类型.此类型在测试方法之外不可用.因此,永远不会调用存根.
是否可以在不指定类型参数的情况下存根通用方法?
我是Hyperlink
控制新手.我希望在常规WPF窗口中有一个超链接,它将通过打开标准浏览器导航到URL.我添加了超链接,但它什么也没做.
在我实现处理程序自己完成工作之前,有人可以确认超链接控件只能在页面内导航吗?
最近一位同事检查了变更集,其中表单<%=(...)%>上的大量表达式被更改为<%:(...)%>.
我有一个模糊的回忆,听到了什么<%:做了,但不记得了.打电话给我的同事已经太晚了,Google和Bing似乎都无法搜索字符串"<%:".
有人可以开导我吗?
wpf ×5
c# ×4
.net ×2
resources ×2
xaml ×2
asp.net ×1
c#-3.0 ×1
clr ×1
data-binding ×1
excel ×1
generics ×1
hyperlink ×1
lambda ×1
mvvm ×1
oledb ×1
rhino-mocks ×1
unit-testing ×1
validation ×1
wpf-4.0 ×1