Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#在运行时返回泛型类型,不带类型参数_C#_Generics_Return - Fatal编程技术网

C#在运行时返回泛型类型,不带类型参数

C#在运行时返回泛型类型,不带类型参数,c#,generics,return,C#,Generics,Return,是否可以返回类型为的对象 IModel< T > 我想到了一个解决办法,比如 公共IModel GetModel(类型t)和一个包装器,用于将其转换为正确的类型 我希望我没有完全错。 这是我的第一个问题。如果您的问题是如何返回IModel的实例,但您不知道编译时t是什么,只是它总是从IFactoryItem派生,那么: 如果在方法输入中不使用t,并且t是一个类,则可以使用协方差: public interface IModel<out T> where T : cla

是否可以返回类型为的对象

 IModel< T >
我想到了一个解决办法,比如

公共IModel GetModel(类型t)和一个包装器,用于将其转换为正确的类型

我希望我没有完全错。
这是我的第一个问题。

如果您的问题是如何返回
IModel
的实例,但您不知道编译时
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);
    }
}

如果您的问题是如何在运行时只知道类型的情况下创建
模型的实例,则其:

 var someType = typeof (SomeFactoryItem);
 var instance = Activator.CreateInstance(typeof (Model<>).MakeGenericType(someType));
var someType=typeof(SomeFactoryItem);
var instance=Activator.CreateInstance(typeof(Model).MakeGenericType(someType));
您仍然需要返回
IModel
,或者,如果可以使用covarience,
IModel

是否可以在不知道类型参数的情况下返回类型为
IModel
的对象

从技术上说没有,但我认为这个问题实际上有点误解。
T
的类型是知道吗,它只是泛型的——事实上,它是如此广为人知,甚至受到限制。注意
其中T:IFactoryItem
,这表示任何试图执行
AddModel
GetModel
函数的东西都必须是实现
IFactoryItem
接口的东西。如果您试图编写调用任一方法并向其中传递除
IFactoryItem
接口实现以外的任何内容的东西,它甚至不会编译

请考虑下面的代码,变量即代码> FETCH < /COD>实际上是与添加的变量<代码>模型< /代码>相同的对象!

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; }
}
类程序
{
静态void Main()
{
var测试=新测试();
var模型=新模型();
测试。添加模型(模型);
var fetch=test.GetModel();
Console.WriteLine(fetch==model
“它确实起作用了……”
:“呃,那应该有用吗?”);
Console.ReadLine();
}
公开课考试
{
专用只读词典_allModelsByType;
公开考试()
{
_allModelsByType=新字典();
}
公共void AddModel(IModel模型),其中T:IFactoryItem
{
_添加(typeof(T),model);
}
公共IModel GetModel(),其中T:IFactoryItem
{
var tmpType=类型(T);
return _allModelsByType.ContainsKey(tmpType)
?_所有模型BYTYPE[tmpType]作为IModel
:null;
}
}
}
内部类FactoryItem:IFactoryItem{}
内部类模型:IModel
{
public FactoryItem值{get;set;}
}
内部接口IFactoryItem{}
内部接口IModel,其中T:IFactoryItem
{
T值{get;set;}
}
运行此程序将输出“它确实有效…”


假设字典中的值与类型键对齐,您的方法看起来非常好。有什么问题?
 var someType = typeof (SomeFactoryItem);
 var instance = Activator.CreateInstance(typeof (Model<>).MakeGenericType(someType));
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; }
}