我有在C#中的以下内容:如何在运行时生成未知类型的实例?
string typename = "System.Int32";
string value = "4";
论文两个字符串应采取生成指定的类型与所指定的值的对象...
的结果应该是:
object o = CreateUnknownType(typename, value);
...
Int32 test = (Int32)o;
我有在C#中的以下内容:如何在运行时生成未知类型的实例?
string typename = "System.Int32";
string value = "4";
论文两个字符串应采取生成指定的类型与所指定的值的对象...
的结果应该是:
object o = CreateUnknownType(typename, value);
...
Int32 test = (Int32)o;
这是你在想什么?
object result = Convert.ChangeType("4", Type.GetType("System.Int32"));
是的,这就是它,谢谢 – haze4real 2009-11-12 14:40:12
你的逻辑在这里似乎有点缺陷。很明显,如果你以后直接将对象转换为实际的类型,那么你必须知道类型。
如果还有其他的东西在这个问题上没有,请详细说明,也许有一个比简单的更合适的答案,“这没有多大意义。”
这看起来像Int32.Parse(字符串)的工作。但要同意其他人的看法,这似乎是“独一无二的”,应该可能会认为手套。
如上所述,这太宽泛且无法一般地解决。
这里有一些选择:
Type type = Type.GetType(typename);
object o = Activator.CreateInstance(type);
这将创建一个typename
被描述的类型的实例。它调用该类型的无参数构造函数。 (缺点:并非所有对象都有一个参数构造。此外,这并设置使用value
的对象的状态。)
Type type = Type.GetType(typename);
object o = Activator.CreateInstance(type, new[] { value });
这将创建typename
被描述的类型的一个实例。它调用该类型的构造函数,它接受string
类型的一个参数。 (缺点:并非所有的对象都具有这样的构造例如,Int32
不具备这样的构造函数,因此你会遇到一个运行时异常。)
Type type = Type.GetType(typename);
object o = Convert.ChangeType(value, type);
这将尝试将字符串value
转换的一个实例所需的类型。尽管如此,这可能导致InvalidCastException
。例如,Convert.ChangeType("4", typeof(FileStream))
显然会失败,因为它应该如此。
事实上,最后一个例子(创建一个FileStream
类型的实例,其初始状态由字符串"4"
确定)显示了一般问题是多么荒谬。有一些建设/转换是无法完成的。
您可能想要重新考虑您尝试解决的问题以避免这种恶作剧。
也许我应该,谢谢你解释的可能性... – haze4real 2009-11-12 14:47:06
通过创建一个名字你知道一个类型的实例(并且应该有一个默认的构造函数):
string typeName = "System.Int32";
Type type = Type.GetType(type);
object o = Activator.CreateInstance(type);
从字符串解析值显然只为一组有限的工种。你可以
Convert.ChangeType
通过PhilipWDictionary<Type,Func<string,object>>
它映射已知类型已知的解析 功能或使用反射来调用 解析(string)方法 假设有一个:
string valueText = "4";
MethodInfo parseMethod = type.GetMethod("Parse");
object value = parseMethod.Invoke(null, new object[] { valueText });
或者您可以使用由.NET 组件模型提供的基础结构 。您可以获取组件的 型转换器,并使用 这样的:
TypeConverter converter = TypeDescriptor.GetConverter(type);
object value = converter.ConvertFromString(valueText);
使用后:
Type type = Type.GetType(typename);
试试这个扩展方法:
public static class ReflectionExtensions
{
public static T CreateInstance<T>(this Type source, params object[] objects)
where T : class
{
var cons = source.GetConstructor(objects.Select(x => x.GetType()).ToArray());
return cons == null ? null : (T)cons.Invoke(objects);
}
}
希望这有助于。
也许你有一组不同的类型,所有这些都实现了一个已知的接口?例如,如果你有几个不同的用户控件,并希望将其中的一个加载到一个容器中,则每个人都可能实现IMyWobblyControl(一个已知接口),但在运行时可能不知道它们要加载哪些内容,可能来自阅读来自某种形式的配置文件的字符串。
在这种情况下,您需要使用反射从类似完整程序集名称加载实际类型,然后将其转换为已知类型以使用它。
当然,你需要确保你的代码处理无效的转换,组装没有发现任何有可能通过的摇晃,因为这东西一起去其他异常...
这里有一个具体的涉及Azure SQL Federations的问题的示例...根据密钥范围将数据分割为单独的数据库。
的键范围的类型有:
SQL/的.Net SQL类型/CLR的.Net
INT/SqlInt32 /的Int32,可空
BIGINT/SqlInt64/Int64类型,Nullable
UNIQUEIDENTIFIER/SqlGuid/Guid,Nullable
VARBINARY(n)时,最大n 900/SqlBytes,SqlBinary /字节[]
理想情况下,C#函数PARAM可以采取以下的.Net SQL类型或CLR .NET类型但沉降上类型的只是一个类别很好。
会有“对象”类型参数是要走的路吗?而且,是否有一种可行的方法来识别类型并相应地进行转换?
的概念是一样的东西:
公共无效FN(obj对象,字符串fedName,串DISTNAME,布尔filteringOn)
{
...弄清楚什么类型obj是保证它是可接受的类型之一...
string key = obj.toString();
return string.Format(“USE FEDERATION {0}({1} ='{2}')WITH RESET,FILTERING = {3}”,fedName,distName,key,(filteringOn?“ON”:“ OFF“));
}
虽然PARAM值被转换为字符串,将重铸/检查上的SQL服务器侧,从而验证它上的应用程序侧是希望的。
而你的问题是?为什么试图创建一个未知的,如果你打算将它转换成一个已知的类型呢? – Lazarus 2009-11-12 14:24:35
问题是:如何在运行时生成未知类型的实例?没关系为什么或者没有,我只想知道它是否可能 – haze4real 2009-11-12 14:52:34
那很容易,是的,这是可能的。这是否可行?可能不会。当你的例子没有意义时,问一些背景是不合理的? – Lazarus 2009-11-12 16:20:28