是否可以返回
类型的对象 IModel< T >
不知道类型参数?
将对象存储在字典中,将Type作为键,将IModel
(作为IModel<T>
的基接口)的对象实现为值。
接口IModel<T>
继承自IModel
,但要执行完整操作,我需要IModel<T>
的对象。 T
需要有IFactoryItem
接口。
但首先是代码:
public IModel<T> GetModel<T>() where T : IFactoryItem
{
Type tmpType = typeof(T);
if (!_allModelsByType.ContainsKey(tmpType))
return null;
return (IModel<T>)_allModelsByType[tmpType];
}
我想到了像
这样的解决方案public IModel GetModel(Type t)和一个将其强制转换为正确类型的包装器。
我希望我并非完全错误。 这是我的第一个问题。
答案 0 :(得分:1)
如果您的问题是如何返回IModel<T>
的实例,但您在编译时不知道T
是什么,只是它始终来自IFactoryItem
然后:
如果您未在方法输入中使用T
,并且T
是一个类,则可以使用协方差:
public interface IModel<out T> where T : class
{
T Value { get; }
}
public class Model<T> : IModel<T> where T : class
{
public T Value { get; set; }
}
class Program
{
static void Main(string[] args)
{
var foo = new Model<string>()
{
Value = "hello world",
};
IModel<object> boo = foo;
Console.WriteLine(boo.Value);
}
}
通过这种方式,您可以传递IModel<IFactoryItem>
而不是IModel<T>
如果您需要值类型,或者您不能使用协方差,那么理想情况下您(如您所建议的那样)第二个非通用接口IModel
将任何值公开为{{ 1}}
object
如果您的问题是如何在运行时只知道类型时创建public interface IModel
{
object Value { get; }
}
public class Model<T> : IModel, IModel<T>
{
public T Value { get; set; }
object IModel.Value => Value;
}
的实例,那么:
Model<T>
您仍然需要返回 var someType = typeof (SomeFactoryItem);
var instance = Activator.CreateInstance(typeof (Model<>).MakeGenericType(someType));
,或者,如果您可以使用协变,IModel
答案 1 :(得分:0)
是否可以在不知道类型参数的情况下返回
IModel<T>
类型的对象?
技术上没有,但我认为实际上这是一个轻微的误解。 T
的类型知道,它只是通用的 - 实际上它是众所周知的,它甚至受到约束。请注意where T : IFactoryItem
,这表示尝试执行AddModel
或GetModel
函数的任何内容都必须是实现IFactoryItem
接口的内容。如果您尝试编写调用任一方法的内容并将其传递给除IFactoryItem
接口的实现之外的任何内容,它甚至不会编译。
请考虑下面的代码,变量即fetch
实际上是与添加的变量model
相同的对象!
class Program
{
static void Main()
{
var test = new Test();
var model = new Model();
test.AddModel(model);
var fetch = test.GetModel<FactoryItem>();
Console.WriteLine(fetch == model
? "It does in fact work..."
: "Uh, that was supposed to work?");
Console.ReadLine();
}
public class Test
{
private readonly Dictionary<Type, object> _allModelsByType;
public Test()
{
_allModelsByType = new Dictionary<Type, object>();
}
public void AddModel<T>(IModel<T> model) where T : IFactoryItem
{
_allModelsByType.Add(typeof(T), model);
}
public IModel<T> GetModel<T>() where T : IFactoryItem
{
var tmpType = typeof(T);
return _allModelsByType.ContainsKey(tmpType)
? _allModelsByType[tmpType] as IModel<T>
: null;
}
}
}
internal class FactoryItem : IFactoryItem { }
internal class Model : IModel<FactoryItem>
{
public FactoryItem Value { get; set; }
}
internal interface IFactoryItem { }
internal interface IModel<T> where T : IFactoryItem
{
T Value { get; set; }
}
运行此程序将输出&#34;它确实有效...&#34;
<iframe width="100%" height="750" src="https://dotnetfiddle.net/Widget/J26ETn" frameborder="0"></iframe>
&#13;