typeof(T)表示内部列表

时间:2015-02-11 07:35:26

标签: c# generics typeof

我正在尝试从REST API反序列化xml输出。反序列化后,我需要检查响应是否有有效数据。

public class Response
{
 public UserWrapper Users { get; set; }
 public MovieWrapper Movies { get; set; }
}

public class UserWrapper
{
    [XmlElement("User")]
    public User[] UserList { get; set; }
}

public class MovieWrapper
{
    [XmlElement("Movie")]
    public Movie[] MovieList { get; set; }
}

public static bool isValidUserResponse(this Response response)
{
 return response.Users != null && response.Users.UserList != null
}

 public static bool isValidMovieResponse(this Response response)
{
 return response.Movies!= null && response.Movies.MovieList != null
}

XML响应结构

<Response>
 <Users>
  <User>...</User>
  <User>...</User>
  <User>...</User>
 </Users>
</Response>

<Response>
 <Movies>
  <Movie>...</Movie>
  <Movie>...</Movie>
  <Movie>...</Movie>
 </Movies>
</Response>

如何将isValidUserResponse()和isValidMovieResponse()作为单一通用方法?

2 个答案:

答案 0 :(得分:3)

你不能仅仅使用泛型 - 至少,不容易。你可以写一些类似的东西:

public static void IsValidResponse<T>(this Response response,
    Func<Response, T> firstPropertyFetcher,
    Func<T, object> secondPropertyFetcher) where T : class
{
    T property = firstPropertyFetcher(response);
    return property != null && secondPropertyFetcher(property) != null;
}

并将其命名为:

response.IsValidResponse(r => r.Users, u => u.UserList);
response.IsValidResponse(r => r.Movies, u => u.MovieList);

......但我不确定那是否更清洁。

或者你可以使用反射来检查Response中的所有属性并查找具有“目标”类型的属性,并验证这些......但它有点难看。< / p>

您是否需要单独验证响应的每个部分?如果没有,您可以考虑为每个班级提供自己的IsValid方法。

或者,我相信有一些一般的开源验证项目可以帮助你 - 但我没有任何经验。

答案 1 :(得分:2)

public class Response
{
    public UserWrapper Users { get; set; }
    public MovieWrapper Movies { get; set; }

    public Response()
    {
        Users = new UserWrapper();
        Movies = new MovieWrapper();
    }

    public bool IsValid<T>() where T : IList
    {
        var property = this.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).First(p => p.PropertyType.Equals(typeof(T)));
        var collection = property.GetValue(this) as IList;
        return collection.Count > 0;
    }
}

public class User
{
    // ...
}

public class Movie
{
    // ...
}

public class UserWrapper : List<User>
{
    // ...
}

public class MovieWrapper : List<Movie>
{
    // ...
}

然后我们得到:

static void Main(string[] args)
        {
            var res = new Response();
            res.Users.Add(new User());
            Console.WriteLine(res.IsValid<UserWrapper>().ToString()); // "true"
            Console.WriteLine(res.IsValid<MovieWrapper>().ToString()); // "false"
        }

所以这就是发生的事情:this.GetType()给我们Response类型对象,它存储有关它的所有元数据;我们获取属于该实例的所有公共属性,并且我们查找第一个具有返回类型(PropertyType)的公共属性,该类型与我们正在寻找的类型相同:T类型。 我们使用property从实例(property.GetValue(this))获取相关集合,然后我们只计算它。

请注意,如果您有两个相同类型的属性 - 此模式将无效。