我有一个这样定义的类Option<T>
:
class Option<T>
{
T Value { get; set; }
bool HasValue { get; }
}
在我的代码的某个时刻,此类的实例通过回调object
(在value
内部传递)发送给我
private void Callback(object value)
{
}
我想将值转换为Option<T>
,但是在编译时我不知道类型T
。
如何“上载”实例以进行检查,例如Value
属性?
答案 0 :(得分:1)
您在评论中告诉我们的唯一一件事就是您要访问HasValue
。那很容易-创建一个界面
public interface IOption
{
bool HasValue { get; }
}
class Option<T> : IOption
{
T Value { get; set; }
bool HasValue { get; }
}
并将收到的object
投射到IOption
。如果您还需要提取值,则需要带有covariant type parameter
public interface IOption<out T> : IOption
{
T Value { get; }
}
class Option<T> : IOption<T>
{
T Value { get; set; }
bool HasValue { get; }
}
然后您就可以将object
强制转换为IOption<object>
,并且对任何T
都可以成功,从而可以将Value
检索为object
。不过,您将无法进行设置。
答案 1 :(得分:0)
如果您知道所有可能性,则可以使用模式匹配:
public static void Main(string[] args)
{
object someOption = new Option<DateTime>() { Value = DateTime.Now};
switch (someOption)
{
case Option<DateTime> dt:
Console.WriteLine($"Date: {dt.Value}");
break;
case Option<string> str:
Console.WriteLine($"String: {str}");
break;
}
}
否则,这可能是您的解决方案。在需要将对象传递给其他泛型方法或在泛型类型中使用它时,有时会使用类似的概念。
interface IOptionHandler
{
void Handle(object option);
}
static class OptionHandler
{
public static IOptionHandler Create(Type targetType)
{
// normally you would check if it really is an Option<T>
// by providing some non-generic interface like IOption
// we skip this part
var typeParam = targetType.GetGenericArguments()[0];
var helperType = typeof(Helper<>).MakeGenericType(typeParam);
return (IOptionHandler) Activator.CreateInstance(helperType);
}
class Helper<T> : IOptionHandler
{
public void Handle(object option)
{
// in this context you can use all the generic powers again
Option<T> myOlOption = (Option<T>) option;
List<Option<T>> whatever = new List<Option<T>>();
whatever.Add(myOlOption);
Console.WriteLine($"{myOlOption.Value.GetType()}: {myOlOption.Value}");
}
}
}
public static void Main(string[] args)
{
object someOption = new Option<DateTime>() { Value = DateTime.Now};
var handler = OptionHandler.Create(someOption.GetType());
handler.Handle(someOption);
}
我通常会缓存创建的帮助对象,但这完全取决于用例。