Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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# - Fatal编程技术网

C# 类限制与原型

C# 类限制与原型,c#,C#,我试图在C#中创建一个函数,它允许我在调用时返回对给定类类型的引用。我所见过的唯一类似于这样的函数类型是在UnrealScript中,即使这样,该函数还是硬编码到它的编译器中。我想知道我是否能用C#做这件事。以下是我的意思(来自UnrealScript源代码的代码片段): 它将返回对类“ActorChild”的对象的引用,并将其设置为变量“myChildRef”。我需要在C#中执行类似的操作 我已经研究过泛型,但似乎要使用它们,我需要在函数所在的类中创建一个instace,并将“generic”

我试图在C#中创建一个函数,它允许我在调用时返回对给定类类型的引用。我所见过的唯一类似于这样的函数类型是在UnrealScript中,即使这样,该函数还是硬编码到它的编译器中。我想知道我是否能用C#做这件事。以下是我的意思(来自UnrealScript源代码的代码片段):

它将返回对类“ActorChild”的对象的引用,并将其设置为变量“myChildRef”。我需要在C#中执行类似的操作

我已经研究过泛型,但似乎要使用它们,我需要在函数所在的类中创建一个instace,并将“generic”参数传递给它。但是,这不是很理想,因为我不需要对某些类使用“Spawn”函数,但无论何时使用它,我仍然需要将泛型参数添加到类中

我想一个简单的问题是,如何返回编译时不知道的类型,以及何时不同的类可能太多而无法捕获

伪代码(坚持UScript类名,即Actor):

//函数Sig
公共类创建(类CreatedClass)
{
返回新的CreatedClass;
}
//函数调用
ActorChild myChild=Create(类'ActorChild');
有什么想法吗

编辑:我希望避免在调用创建的类时出现显式类型转换。如果我能在创建的方法中类型转换到所需的对象,并返回“未知类型”,不管是什么,我将非常高兴


编辑2:感谢您的回答。

您可以使用类系统。键入以表示类。要获取对类型对象的引用,可以使用typeof(在实际定义类的范围内)

或者Type.GetType函数(如果您只知道类型的名称)

然后可以使用反射API创建实例

public object Create(System.Type ClassToCreate)
{
    return ClassToCreate.GetConstructor(Type.EmptyTypes).Invoke(null);
}

可以使用类System.Type来表示类。要获取对类型对象的引用,可以使用typeof(在实际定义类的范围内)

或者Type.GetType函数(如果您只知道类型的名称)

然后可以使用反射API创建实例

public object Create(System.Type ClassToCreate)
{
    return ClassToCreate.GetConstructor(Type.EmptyTypes).Invoke(null);
}

通过反射和一种称为动态方法调用的方法,可以很容易地完成您试图完成的任务

基本上,您将使用类型对象、Activator.CreateInstance方法和其他一些不错的类,如MethodInfo和ParameterInfo

下面是一个让您开始学习的示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Reflection
{
    class SomeClass
    {
        private string StringPrimer = "The parameter text is: ";
        public SomeClass(string text)
        {
             Console.WriteLine(StringPrimer + text);
        }
        public string getPrimer() //supplies the Primer in upper case, just for kicks
        {
            return StringPrimer.ToUpper();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            SomeClass s = new SomeClass("this is an example of the classes normal hard-coded function.\nNow try feeding in some text");
            string t = Console.ReadLine();

            Console.WriteLine("Now feed in the class name (SomeClass in this case)");
            Type myType = Type.GetType("Reflection."+Console.ReadLine()); //Stores info about the class.
            object myClass = Activator.CreateInstance(myType, new object[] { t }); //This dynamically calls SomeClass and sends in the text you enter as a parameter

            //Now lets get the string primer, using the getPrimer function, dynamically
            string primer = (string)myType.InvokeMember("getPrimer",
                                                        BindingFlags.InvokeMethod | BindingFlags.Default,
                                                        null,
                                                        myClass,
                                                        null); //This method takes the name of the method, some Binding flags,
                                                              //a binder object that I left null,
                                                              //the object that the method will be called from (would have been null if the method was static)
                                                              //and an object array of parameters, just like in the CreateInstance method.
            Console.WriteLine(primer);
        }
    }
}

通过反射和一种称为动态方法调用的方法,可以很容易地完成您试图完成的任务

基本上,您将使用类型对象、Activator.CreateInstance方法和其他一些不错的类,如MethodInfo和ParameterInfo

下面是一个让您开始学习的示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Reflection
{
    class SomeClass
    {
        private string StringPrimer = "The parameter text is: ";
        public SomeClass(string text)
        {
             Console.WriteLine(StringPrimer + text);
        }
        public string getPrimer() //supplies the Primer in upper case, just for kicks
        {
            return StringPrimer.ToUpper();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            SomeClass s = new SomeClass("this is an example of the classes normal hard-coded function.\nNow try feeding in some text");
            string t = Console.ReadLine();

            Console.WriteLine("Now feed in the class name (SomeClass in this case)");
            Type myType = Type.GetType("Reflection."+Console.ReadLine()); //Stores info about the class.
            object myClass = Activator.CreateInstance(myType, new object[] { t }); //This dynamically calls SomeClass and sends in the text you enter as a parameter

            //Now lets get the string primer, using the getPrimer function, dynamically
            string primer = (string)myType.InvokeMember("getPrimer",
                                                        BindingFlags.InvokeMethod | BindingFlags.Default,
                                                        null,
                                                        myClass,
                                                        null); //This method takes the name of the method, some Binding flags,
                                                              //a binder object that I left null,
                                                              //the object that the method will be called from (would have been null if the method was static)
                                                              //and an object array of parameters, just like in the CreateInstance method.
            Console.WriteLine(primer);
        }
    }
}
不要使用泛型类,而是使用泛型方法:

public T Spawn(),其中T:new()
{
返回新的T();
}
话虽如此,我假设您希望做的不仅仅是盲目创建实例,否则您可以自己调用
new MyClass()

而不是使用泛型类,而是使用泛型方法:

public T Spawn(),其中T:new()
{
返回新的T();
}

话虽如此,我假设您希望做的不仅仅是盲目地创建一个实例,否则您可以自己调用
new MyClass()

这不就是“Type.GetType只在mscorlib中查看”问题吗?真的吗?我知道,如果将assemblyname放在类型名称之后,它也会在其他程序集中查找。请参阅MSDN中AssemblyQualifiedName的文档。这需要将类型转换为“object”或将“object”类型转换为方法签名中指定的任何返回值。我想避免这种情况。这不是因为“Type.GetType只在mscorlib中显示”问题吗?真的吗?我知道,如果将assemblyname放在类型名称之后,它也会在其他程序集中查找。请参阅MSDN中AssemblyQualifiedName的文档。这需要将类型转换为“object”或将“object”类型转换为方法签名中指定的任何返回值。我想避免这样。谢谢-显然我读得不够。我想有一个泛型方法,你也需要一个泛型类。谢谢-显然我读得不够多。我认为要有一个泛型方法,还需要一个泛型类。
System.Type t = Type.GetType("NamespaceFoo.ActorChild");
public object Create(System.Type ClassToCreate)
{
    return ClassToCreate.GetConstructor(Type.EmptyTypes).Invoke(null);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Reflection
{
    class SomeClass
    {
        private string StringPrimer = "The parameter text is: ";
        public SomeClass(string text)
        {
             Console.WriteLine(StringPrimer + text);
        }
        public string getPrimer() //supplies the Primer in upper case, just for kicks
        {
            return StringPrimer.ToUpper();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            SomeClass s = new SomeClass("this is an example of the classes normal hard-coded function.\nNow try feeding in some text");
            string t = Console.ReadLine();

            Console.WriteLine("Now feed in the class name (SomeClass in this case)");
            Type myType = Type.GetType("Reflection."+Console.ReadLine()); //Stores info about the class.
            object myClass = Activator.CreateInstance(myType, new object[] { t }); //This dynamically calls SomeClass and sends in the text you enter as a parameter

            //Now lets get the string primer, using the getPrimer function, dynamically
            string primer = (string)myType.InvokeMember("getPrimer",
                                                        BindingFlags.InvokeMethod | BindingFlags.Default,
                                                        null,
                                                        myClass,
                                                        null); //This method takes the name of the method, some Binding flags,
                                                              //a binder object that I left null,
                                                              //the object that the method will be called from (would have been null if the method was static)
                                                              //and an object array of parameters, just like in the CreateInstance method.
            Console.WriteLine(primer);
        }
    }
}
public T Spawn<T>() where T : new()
{
    return new T();
}