我有一个用C#写的项目。我试图将对象强制转换为接受枚举对象作为泛型参数的类。
我有以下课程
public class GenericEnumViewModel<TEnum> where TEnum : struct
{
[Required]
public TEnum? Value { get; set; }
public IEnumerable<SelectListItem> Options { get; set; }
}
下面是我的一个枚举对象的示例
public enum TestEnum
{
First,
Second,
Third,
Fourth
}
最后,我有一个object
类型的变量,如下所示
object obj = new GenericEnumViewModel<TestEnum>(); // Notice at this point I don't know that the generic type is `TestEnum` it could be any Enum.
如何检查变量obj
是否实现了GenericEnumViewModel<Enum>
?另外,如何使一个名为castedObj
的新变量成为GenericEnumViewModel<Enum>
我正在尝试访问castedObj.Value
和castedObj.Options
。
我想做这样的事
var castedObj = obj as GenericEnumViewModel<Enum>;
if(castedObj != null)
{
// do something with castedObj.Value and castedObj.Options.
}
发布于 2018-08-23 14:33:22
如何检查变量obj是否实现了GenericEnumViewModel?
您可以使用反射来完成此操作:
object obj = new GenericEnumViewModel<TestEnum>();
var objType = obj?.GetType();
var enumType =
objType != null && objType.IsGenericType && objType.GetGenericTypeDefinition() == typeof(GenericEnumViewModel<>) ?
objType.GetGenericArguments()[0] :
throw new InvalidOperationException($"Object is not a closed type of {typeof(GenericEnumViewModel<>).FullName}");
另外,如何使一个名为castedObj的新变量成为GenericEnumViewModel
由于多种原因,这是不可能的。下面的行不会编译:
// this code is invalid!
GenericEnumViewModel<Enum> model = new GenericEnumViewModel<TestEnum>();
首先,协方差只允许用于C#中的接口、数组和委托。
此外,即使类允许协方差,System.Enum也是引用类型,而枚举是值类型。将枚举值分配给System.Enum变量涉及到拳击。这本身就使上述任务不可能完成。
但是,您可以通过这样的非泛型接口(或抽象基类)来解决这个问题:
public interface IGenericEnumViewModel
{
Enum Value { get; }
GenericEnumViewModel<SelectListItem> Options { get; }
}
public class GenericEnumViewModel<TEnum> : IGenericEnumViewModel where TEnum : struct
{
[Required]
public TEnum? Value { get; set; }
public GenericEnumViewModel<SelectListItem> Options { get; set; }
Enum IGenericEnumViewModel.Value => Value.HasValue ? Value.Value : (Enum)null;
}
// ...
if (obj is IGenericEnumViewModel castedObj)
{
// do something with castedObj.Value and castedObj.Options.
Enum value = castedObj.Value;
// ...
}
奖金
从C# 7.3 可以在泛型类型约束中使用Enum。!
public class GenericEnumViewModel<TEnum> : IGenericEnumViewModel where TEnum : struct, Enum
{
// ...
}
发布于 2018-08-23 12:12:40
您可以添加新的接口并显式地实现它。然后,您可以使用模式匹配,这是在C# 7.0中引入的。
public interface IGenericEnumViewModel
{
object Value { get; set; }
GenericEnumViewModel<SelectListItem> Options { get; set; }
}
public class GenericEnumViewModel<TEnum> : IGenericEnumViewModel where TEnum : struct
{
public TEnum? Value { get; set; }
public GenericEnumViewModel<SelectListItem> Options { get; set; }
object IGenericEnumViewModel.Value {
get {return Value;}
set {Value = (TEnum?)value;}
}
然后:
if(obj is IGenericEnumViewModel c)
{
//c is IGenericEnumViewModel
}
https://stackoverflow.com/questions/51993451
复制