我在当前的项目中做了很多反思,我正在努力提供一些帮助方法,以保持一切都很整洁。
我想提供一对方法来确定类型或实例是否实现IEnumerable
- 无论类型T
如何。这就是我现在所拥有的:
public static bool IsEnumerable(this Type type)
{
return (type is IEnumerable);
}
public static bool IsEnumerable(this object obj)
{
return (obj as IEnumerable != null);
}
当我使用
测试它们时Debug.WriteLine("Type IEnumerable: " + typeof(IEnumerable).IsEnumerable());
Debug.WriteLine("Type IEnumerable<>: " + typeof(IEnumerable<string>).IsEnumerable());
Debug.WriteLine("Type List: " + typeof(List<string>).IsEnumerable());
Debug.WriteLine("Type string: " + typeof(string).IsEnumerable());
Debug.WriteLine("Type DateTime: " + typeof(DateTime).IsEnumerable());
Debug.WriteLine("Instance List: " + new List<string>().IsEnumerable());
Debug.WriteLine("Instance string: " + "".IsEnumerable());
Debug.WriteLine("Instance DateTime: " + new DateTime().IsEnumerable());
我得到了这个结果:
Type IEnumerable: False
Type IEnumerable<>: False
Type List: False
Type string: False
Type DateTime: False
Instance List: True
Instance string: True
Instance DateTime: False
类型方法似乎根本不起作用 - 我原本期望至少为true
匹配System.Collections.IEnumerable
。
我知道string
在技术上是可以枚举的,尽管有一些警告。但是,理想情况下,在这种情况下,我需要帮助方法为它返回false
。我只需要定义了IEnumerable<T>
类型的实例来返回true
。
我可能只是错过了一些相当明显的东西 - 有人能指出我正确的方向吗?
答案 0 :(得分:40)
以下一行
return (type is IEnumerable);
询问“Type
,type
的实例是否为IEnumerable
”,显然不是。
你想做的是:
return typeof(IEnumerable).IsAssignableFrom(type);
答案 1 :(得分:7)
除Type.IsAssignableFrom(Type)
外,您还可以使用Type.GetInterfaces()
:
public static bool ImplementsInterface(this Type type, Type interface)
{
bool implemented = type.GetInterfaces().Contains(interface);
return implemented;
}
这样,如果您想检查多个接口,可以轻松修改ImplementsInterface
以获取多个接口。
答案 2 :(得分:1)
要检查某种类型是否实现IEnumerable ,无论T是否是,都需要检查GenericTypeDefinition。
<!-- https://stackoverflow.com/a/28571411/3195477 -->
<!-- https://stackoverflow.com/a/7487670/3195477 -->
<Style
x:Key="RadioButtonListBoxStyle"
TargetType="{x:Type ListBox}"
>
<Setter
Property="BorderBrush"
Value="Transparent"
/>
<Setter
Property="Background"
Value="Transparent"
/>
<Setter
Property="KeyboardNavigation.DirectionalNavigation"
Value="Cycle"
/>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}">
<Setter
Property="Margin"
Value="2,2,2,0"
/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Background="Transparent">
<RadioButton
Content="{TemplateBinding ContentPresenter.Content}"
ContentTemplate="{TemplateBinding ContentPresenter.ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentPresenter.ContentTemplateSelector}"
IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>