【问题标题】:Creating a JavascriptConverter for a Generic Type为泛型类型创建 JavascriptConverter
【发布时间】:2011-12-01 12:02:28
【问题描述】:

假设我有一个名为MyClass<T> 的通用类,我如何创建一个JavascriptConverter,它将用于任何可能的T(可能是MyClass<OtherClass>MyClass<SimpleClass>)?

我尝试在我的转换器中执行以下操作:

public Enumerable<Type> SupportedTypes
{
  get
  {
    return new List<Type>(){ typeof(MyClass<>) };
  }
}

但无济于事。

有什么想法吗?这可能吗?
如果没有,有没有其他方法可以达到同样的效果?

【问题讨论】:

  • 这可能是一个想法,说明您想要一个通用 MyClass&lt;T&gt; 可以生成的所有具体类型的列表(对 T 有任何限制吗?)。这样任何回答者都不必查找JavascriptConverter 是什么。
  • 问题是我一开始不知道可能的 T 列表。对 T 的唯一限制是它是一个类并且有一个默认的 ctor

标签: c# asp.net-mvc serialization


【解决方案1】:

如果你真的想要这个,完全没有过滤器:

using System.Linq;

....

var concreteGenericTypes =
    (from assembly in AppDomain.CurrentDomain.GetAssemblies()
     from T in assembly.GetTypes()
     where T.IsClass && T.GetConstructor(new Type[] { }) != null
     select typeof(MyClass<>).MakeGenericType(T)).ToList();

它获取所有加载的程序集,然后是这些程序集的所有类型,然后根据您的泛型 where 条件进行过滤,最后它从您的类和类型中创建一个具体的泛型类型。

【讨论】:

  • 在 JavaScriptSerializer 上使用反射器,我现在知道没有其他方法了,真可惜……我想知道这是否是一种设计选择,如果是这样,为什么……
【解决方案2】:

如果你是泛型类型的作者,你应该创建一个你的泛型类型继承自的接口。例如:

public interface IResultSet
{
    long TotalItems { get; }
    IEnumerable Items { get; }
}

public class ResultSet<T> : IResultSet, IEnumerable<T>
{
    private IEnumerable<T> _enumerable;
    private int _totalItems;

    public ResultSet(IEnumerable<T> enumerable,
                     int totalItems)
    {
        _enumerable = enumerable;
        _totalItems = totalItems;
    }

    public IEnumerable Items { get { return _enumerable; } }
    public long TotalItems { get{ return _totalItems; } }

    public IEnumerator<T> GetEnumerator()
    {
        return _enumerable.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return _enumerable.GetEnumerator();
    }
}

public class ResultSetConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get
        {
            return new[] { typeof(IResultSet) };
        }
    }

    ...

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        if (!typeof(IResultSet).IsAssignableFrom(obj.GetType()))
        {
            return null;
        }

        var resultSet = obj as IResultSet;
        var json = new Dictionary<string, object>();

        json["totalItems"] = resultSet.TotalItems;
        json["items"] = resultSet.Items;

        return json;
    }
}

【讨论】:

    【解决方案3】:

    据我所知,由于 javascript 的类型很松散,因此不需要考虑泛型参数。
    不过,您可以尝试使用 instanceof 进行测试。 检查这个问题:
    What is the instanceof operator in JavaScript?
    它可以满足您的需求,至少是检查类型部分。

    【讨论】:

    • MyClass 实例需要特殊的 (json) 序列化,因此需要创建自定义序列化。这与 javascript 的松散类型行为没有直接关系...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    相关资源
    最近更新 更多