在运行时键入标识符

时间:2013-11-22 21:18:32

标签: c# types runtime identifier

以下是不可能的。

var dataType = Type.GetType("System.String");

//magic here

var hs = new HashSet<dataType>();

错误中的上述结果:找不到类型或命名空间名称'dataType'(您是否缺少using指令或程序集引用?)

中间是否有一些神奇的功能让它发挥作用?如果没有,实现预期目标的可行方法是什么?谢谢。

编辑:试图通过简短来提供帮助,但我需要提供更多详细信息。

假设我们有这样的事情:

public static T Deserialize<T>(string json)
{
    var serializer = new JavaScriptSerializer();
    return serializer.Deserialize<T>(json);
}

让我们假设序列化对象类型存储为字符串。我们如何将类型反序列化为字符串。我有一些工作要考虑,但希望有一些涉及我不熟悉的运行时类型标识符。

3 个答案:

答案 0 :(得分:2)

你能得到的最接近的是:

object hs = Activator.CreateInstance(
       typeof(HashSet<>).MakeGenericType(dataType));

然而,真的难以使用 - HashSet<T>没有特别可用的非通用API,因此我会考虑 你想做什么。

答案 1 :(得分:1)

我觉得你能做的最好的事情是:

var dataType = Type.GetType("System.String");

// This is your magic.
var hst = typeof(HashSet<>).MakeGenericType(dataType);
var hs = (IEnumerable)Activator.CreateInstance(hst);  
var add = hst.GetMethod("Add");

IEnumerable是由HashSet<T>实现的唯一有用的非通用接口

现在,添加项目:

add.Invoke(hs, new object[] { "Test 1" });
add.Invoke(hs, new object[] { "Test 2" });
add.Invoke(hs, new object[] { "Test 3" });
add.Invoke(hs, new object[] { "Test 1" });

所以你可以foreach覆盖它,但是当你再次回到object时它仍然没用。您可能然后可能尝试dynamic并对该项目进行鸭子输入:

foreach (dynamic item in hs)
{
    // item.Length would work here, for instance.
}

答案 2 :(得分:0)

鉴于@Marc Gravell没有暗示这一点,我猜这有什么问题,但你可以尝试这样的事情:

public class HashSetGenerator
{
    public static HashSet<T> GetHashSet<T>(T testType) 
    {
        return new HashSet<T>();
    } 
}

然后您可以像这样生成HashSet:

public static void Main(string[] args)
{
    HashSet<string> stringHash = HashSetGenerator.GetHashSet("string");
    HashSet<int> intHash = HashSetGenerator.GetHashSet(123);
}