C# 中参数的通配符

Wildcard for parameter in C#

对于我想用来生成部分视图的一些视图模型,我至少有四种不同的 类。问题是每个局部视图都以完全相同的方式生成下拉列表。

public class LocalityGeneratorForm
{
    [Key]
    public int id { get; set; }
    [Display(Name = "Description of the field")]
    public Locality[] locality { get; set; }
    public virtual ICollection<Locality> Localities { get; }
}

public class GoalGeneratorForm
{
    [Key]
    public int id { get; set; }
    [Display(Name = "A different description of the field")]
    public Goal[] goal { get; set; }
    public virtual ICollection<Goal> Goals { get; }
}

public class ProcessGeneratorForm
{
    [Key]
    public int id { get; set; }
    [Display(Name = "A third description of the field")]
    public Process[] process { get; set; }
    public virtual ICollection<Process> Processes { get; }
}

public class FieldGeneratorForm
{
    [Key]
    public int id { get; set; }
    [Display(Name = "The other new description of the field")]
    public Field[] field { get; set; }
    public virtual ICollection<Field> Fields { get;  }
}

好的,所以所有这些 ViewModel 都非常相似,它们只是 ICollection 的类型不同。现在,为了生成 HTML 字符串,我将使用一个带有两个参数的函数,一个是用作模板的局部视图的名称,另一个是模型。

所以我希望能够创建愿意接受上面或将来 类 的任何实例的方法,也许更多。

private string ConvertViewToString( string viewName, <GenericClass> model ) 
{
    //-- Do stuff..
    return "My HTML";
}

第一个问题是,是否可以,如果可以,我该如何声明泛型参数?谢谢!

如果你想使用通用方法,你可以简单地做:

private string ConvertViewToString<T>(string viewName, T model) {
    //-- Do stuff..
    return "My HTML";
}

// How to call this method?
LocalityGeneratorForm localGenForm = new LocalityGeneratorForm(); /* Simple instancing */

// in this case, T will automatically LocalityGeneratorForm.
ConvertViewToString(some_string, localGenForm);

// or you can explicit define what T type is
ConvertViewToString<LocalityGeneratorForm>(some_string, localGenForm);

并且如果要限制类型参数T的类型,可以使用where.

如果你真的想限制 ConvertViewToString 方法将采用 SomethingTopModelClass 并且它仅是派生类型,你可以这样使用:

private string ConvertViewToString<T>(string viewName, T model) where T: SomethingTopModelClass {
    //-- Do stuff..
    return "My HTML";
}

我的解释可能难以理解(英文不好:S),所以我建议您阅读下面的文档。

C# Generics (MSDN)

C# Generics - Where (MSDN)

我认为您需要的不是通用的 method/class。实现此目的的最佳方法是修改 ConvertViewToString 以接受接口而不是特定实现。将接口注入到方法中将在未来具有更大的灵活性。

public interface IHtmlElement {
    string ToHtmlString();
}

public class LocalityGeneratorForm : IHtmlElement
{
    [Key]
    public int id { get; set; }
    [Display(Name = "Description of the field")]
    public Locality[] locality { get; set; }
    public virtual ICollection<Locality> Localities { get; }
    public string ToHtmlString()
    {
        // convert Locality to html string representation
        return "<p>HTML element string for Locality</p>"
    }
}

public class GoalGeneratorForm : IHtmlElement
{
    [Key]
    public int id { get; set; }
    [Display(Name = "A different description of the field")]
    public Goal[] goal { get; set; }
    public virtual ICollection<Goal> Goals { get; }
    public string ToHtmlString()
    {
        // convert Goal to html string representation
        return "<p>HTML element string for Goal</p>"
    }
}

在下一步中,您可以这样 ConverViewToString 实现:

private string ConvertViewToString( string viewName, IHtmlElement element ) 
{
    //-- Do stuff..
    return element.ToHtmlString();
}

这就是将所有内容组合在一起的方法:

var locality = new LocalityGeneratorForm();
var goal = new GoalGeneratorForm();

var htmlLocality = ConvertViewToString("some name", locality);
var htmlGoal = ConvertViewToString("some name", goal);

希望我的回答可以帮助您使实施更加灵活。