Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.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# 从Activator.CreateInstance()而不是对象返回所需类型_C#_C# 4.0_System.reflection - Fatal编程技术网

C# 从Activator.CreateInstance()而不是对象返回所需类型

C# 从Activator.CreateInstance()而不是对象返回所需类型,c#,c#-4.0,system.reflection,C#,C# 4.0,System.reflection,我正在尝试创建一个指定类型的实例无论用户想要什么。有关我的目的的快速说明,请参见下面的代码: static void Main(string[] args) { object o = GetInstance(typeof(int)); Console.WriteLine("Created type: {0}", o.GetType().FullName); } public static object GetInstance(Ty

我正在尝试创建一个指定
类型的实例
无论用户想要什么。有关我的目的的快速说明,请参见下面的代码:

    static void Main(string[] args)
    {
        object o = GetInstance(typeof(int));
        Console.WriteLine("Created type: {0}", o.GetType().FullName);
    }

    public static object GetInstance(Type t)
    {
        Console.WriteLine("Creating instance of {0}", t.FullName);
        return Activator.CreateInstance(t);
    }
问题是
Activator.CreateInstance()
默认情况下返回
对象。此方法还有一个重载,如
T Activator.CreateInstance()
,它是无参数的,返回指定为
T
的类型

但是,问题是调用此方法时,
T
应该是硬编码的,因此应该是固定值。我试图创建所需类的实例,并将其作为其类型返回

现在,如果使用此方法,您应该编写如下内容:

int i = GetInstance(typeof(int)) as int
我试图将其简化为:

int i = GetInstance(typeof(int))
有没有一种方法可以在
GetInstance
中进行强制转换,并将
转换为int
重复?这样,我的返回类型(以及我将对象转换到的类型)在编译时将是未知的

在我看来,这似乎是不可能的,但如果你能想出办法,我将不胜感激


编辑:我被卡住的地方是,例如,当你在施法时,如果你使用的是泛型方法,你可以执行
返回(T)结果
,但不能执行
键入T=。。。;返回(t)结果
这不起作用。您不能强制转换为作为编译时未知的参数传递给您的类型

实际上,您可以这样编写
GetInstance

static T GetInstance<T>()
{
    return Activator.CreateInstance<T>();
}
public object GetInstance(Type type)
{
    return Activator.CreateInstance(type);
}

int i = GetInstance(typeof(int)) as int;


public T GetInstance<T>()
{
    return Activator.CreateInstance<T>();
}

int i = GetInstance<int>();


public T GetInstance<T>(T template)
{
    return Activator.CreateInstance<T>();
}

int i = GetInstance(0);
static T GetInstance()
{
返回Activator.CreateInstance();
}
并使用它:

int j = GetInstance<int>();
int j=GetInstance();

实际上,您可以这样编写
GetInstance

static T GetInstance<T>()
{
    return Activator.CreateInstance<T>();
}
public object GetInstance(Type type)
{
    return Activator.CreateInstance(type);
}

int i = GetInstance(typeof(int)) as int;


public T GetInstance<T>()
{
    return Activator.CreateInstance<T>();
}

int i = GetInstance<int>();


public T GetInstance<T>(T template)
{
    return Activator.CreateInstance<T>();
}

int i = GetInstance(0);
static T GetInstance()
{
返回Activator.CreateInstance();
}
并使用它:

int j = GetInstance<int>();
int j=GetInstance();

这可能有助于您创建所需类型的实例:

public class ConcreteFactory<T>  : AbstractFactory<T>
    {
        public override T CreateInstance(string typeName,params object[] parameters)
        {
            var path = Assembly.GetExecutingAssembly().CodeBase;
            var assembly = Assembly.LoadFrom(path);
            var type = assembly.GetTypes().SingleOrDefault(t => t.Name == typeName);
            return (T)Activator.CreateInstance(type, parameters);
        }
}
公共类ConcreteFactory:AbstractFactory
{
public override T CreateInstance(字符串类型名,参数对象[]参数)
{
var path=Assembly.getExecutionGassembly().CodeBase;
var assembly=assembly.LoadFrom(路径);
var type=assembly.GetTypes().SingleOrDefault(t=>t.Name==typeName);
return(T)Activator.CreateInstance(类型、参数);
}
}

此处的关键是泛型类型T可用于强制转换所创建的实例,这可作为模板使用参数化构造函数创建任何类型的实例

这可能有助于您创建所需类型的实例:

public class ConcreteFactory<T>  : AbstractFactory<T>
    {
        public override T CreateInstance(string typeName,params object[] parameters)
        {
            var path = Assembly.GetExecutingAssembly().CodeBase;
            var assembly = Assembly.LoadFrom(path);
            var type = assembly.GetTypes().SingleOrDefault(t => t.Name == typeName);
            return (T)Activator.CreateInstance(type, parameters);
        }
}
公共类ConcreteFactory:AbstractFactory
{
public override T CreateInstance(字符串类型名,参数对象[]参数)
{
var path=Assembly.getExecutionGassembly().CodeBase;
var assembly=assembly.LoadFrom(路径);
var type=assembly.GetTypes().SingleOrDefault(t=>t.Name==typeName);
return(T)Activator.CreateInstance(类型、参数);
}
}
这里的关键是泛型类型T可用于强制转换所创建的实例,这可作为模板使用参数化构造函数创建任何类型的实例

遵循已知模式 这不是一个新问题。这是任何允许特定类型返回值的API都面临的问题。例如,像Newtonsoft这样的JSON解析库(即2019年由.NET程序员下载的最流行的.NET包)必须能够解析字符串并返回特定于类型的对象,这在编译时可能是已知的,也可能是未知的。学习他们的榜样可能是有道理的

Newtonsoft公开了三种方法来指定反序列化时的类型。您可以按照当前所做的操作:

//Cast required
var result = JsonConvert.DeserializeObject(text, typeof(MyType)) as MyType;  
您可以使用通用方法:

//No cast required, but you have to hardcode a type as a type parameter
var result = JsonConvert.DeserializeObject<MyType>(text);  
以下是您的做法:

因此,要使其正常工作,您的代码可能如下所示:

static T GetInstance<T>()
{
    return Activator.CreateInstance<T>();
}
public object GetInstance(Type type)
{
    return Activator.CreateInstance(type);
}

int i = GetInstance(typeof(int)) as int;


public T GetInstance<T>()
{
    return Activator.CreateInstance<T>();
}

int i = GetInstance<int>();


public T GetInstance<T>(T template)
{
    return Activator.CreateInstance<T>();
}

int i = GetInstance(0);
公共对象GetInstance(类型)
{
返回Activator.CreateInstance(类型);
}
inti=GetInstance(typeof(int))作为int;
公共T GetInstance()
{
返回Activator.CreateInstance();
}
int i=GetInstance();
公共T GetInstance(T模板)
{
返回Activator.CreateInstance();
}
int i=GetInstance(0);
如果您这样做,很难想象任何程序员在使用您的库时都会遇到问题,因为他们应该已经熟悉这种方法。

遵循一种已知的模式 这不是一个新问题。这是任何允许特定类型返回值的API都面临的问题。例如,像Newtonsoft这样的JSON解析库(即2019年由.NET程序员下载的最流行的.NET包)必须能够解析字符串并返回特定于类型的对象,这在编译时可能是已知的,也可能是未知的。学习他们的榜样可能是有道理的

Newtonsoft公开了三种方法来指定反序列化时的类型。您可以按照当前所做的操作:

//Cast required
var result = JsonConvert.DeserializeObject(text, typeof(MyType)) as MyType;  
您可以使用通用方法:

//No cast required, but you have to hardcode a type as a type parameter
var result = JsonConvert.DeserializeObject<MyType>(text);  
以下是您的做法:

因此,要使其正常工作,您的代码可能如下所示:

static T GetInstance<T>()
{
    return Activator.CreateInstance<T>();
}
public object GetInstance(Type type)
{
    return Activator.CreateInstance(type);
}

int i = GetInstance(typeof(int)) as int;


public T GetInstance<T>()
{
    return Activator.CreateInstance<T>();
}

int i = GetInstance<int>();


public T GetInstance<T>(T template)
{
    return Activator.CreateInstance<T>();
}

int i = GetInstance(0);
公共对象GetInstance(类型)
{
返回Activator.CreateInstance(类型);
}
inti=GetInstance(typeof(int))作为int;
公共T GetInstance()
{
返回Activator.CreateInstance();
}
int i=GetInstance();
公共T GetInstance(T模板)
{
返回Activator.CreateInstance();
}
int i=GetInstance(0);

如果您这样做,很难想象任何程序员在使用您的库时都会遇到问题,因为他们应该已经熟悉了这种方法。

int i=GetInstance(typeof(int))中的类型硬编码为int
?它要求在编译时知道类型-这与
Activator.CreateInstance()
的要求相同。GetInstance方法的客户现在使用
int i=GetInstance(typeof(in