可能重复:
TargetType="controlType" 和 TargetType="{x:Type controlType}"</a> 之间的区别
何时使用 {x:Type ...}?
在TargetType="controlType" 和 TargetType="{x:Type controlType}"的区别中,我可以看到这些不同的设置类型的方法基本相同。但我想知道是否有任何性能影响,因为我猜 {x:Type} 将实例化一个标记对象。
可能重复:
TargetType="controlType" 和 TargetType="{x:Type controlType}"</a> 之间的区别
何时使用 {x:Type ...}?
在TargetType="controlType" 和 TargetType="{x:Type controlType}"的区别中,我可以看到这些不同的设置类型的方法基本相同。但我想知道是否有任何性能影响,因为我猜 {x:Type} 将实例化一个标记对象。
在这里谈论性能是缺少树木的树林。
如果使用string
值,WPF 将使用值转换器将其转换为Type
对象;否则它将使用标记扩展。在这两种情况下,一个简单的实现都会创建一个额外的对象。因此,我看不出如何假设这两种情况中的任何一种创建的对象都比另一种少。
.NET 缓存并重用这些类的单例实例是很有可能的(需要检查 MS 源来确认),因为它们已知是无状态的。
因此,我认为在这种情况下,性能考虑完全不合适。我的观点是使用它会更好,{x:Type}
因为从 XAML 中就可以清楚地知道产生了什么样的值。
我建议少创建一个对象将有利于性能。但是,在这种情况下,性能增益可能非常小,因此您最好考虑代码的可读性。
我总是使用{x:Type someType}
它,因为它清楚地表明这是我正在谈论的一种类型。
当我稍后更改内容时,我总是可以搜索{x:Type
.
正如乔恩所指出的,在这两种情况下,“转换器”都用于基于字符串返回类型。
使用时x:Type
,它实际上是在使用TypeExtension。如果你在 Reflector 中查看这段代码,你会发现它基本上是这样的:
IXamlTypeResolver service = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
return service.Resolve(<<"typenamehere">>);
当您简单地传递一个字符串值(即您不使用x:Type
)时,就会使用一个类型转换器。在这种情况下,由于目标属性是 Type,因此使用的转换器是 TypeTypeConverter。
如果您查看 TypeTypeConverter 的 ConvertFrom 方法,您会发现它执行与 TypeExtension 相同的操作。
因此,字符串到 Type 的转换代码是相同的。因此,唯一的区别在于 TypeExtension 与 TypeTypeConverter 的实例化。
无论哪种情况,都会根据需要创建一个新实例,但框架更有可能重用 TypeTypeConverter。这也可能是未来的优化,但可能不太可能。
无论哪种方式,我怀疑您会注意到使用一种方法或另一种方法的任何形式的性能改进。
值得注意的是,在将类型名称提供为字符串的情况下,既不使用 TypeConverter 也不使用 MarkupExtension。
根据 MSDN -
支持 Typename-as-String 的类型属性
WPF 支持无需使用 x:Type 标记扩展即可指定类型 Type 的某些属性的值的技术。相反,您可以将值指定为命名类型的字符串。这方面的示例是 ControlTemplate.TargetType 和 Style.TargetType。不通过类型转换器或标记扩展提供对这种行为的支持。相反,这是通过 FrameworkElementFactory 实现的延迟行为。