泛型类型的集合

发布于 2024-09-24 18:25:21 字数 947 浏览 3 评论 0原文

我有一个对象(表单),其中包含一个集合(.Fields),我想包含通用类(FormField)的实例。

FormField 简单地定义如下:

public class FormField<T>
{
    private Form Form;
    public T Value { get; set; }
    public string Name { get; set; }

    public void Process()
    {
        // do something
    }

    public FormField(Form form, string name, T value)
    {
        this.Name = name;
        this.Value = value;
        this.Form = form;
    }
}

这允许我拥有 FormField、FormField 等,并且该部分工作得很好。 我想要的是“Formfields”的集合,无论类型如何,但我被迫定义一个类型(看起来),例如:

public class Form
{

    string Code { get; set; }
    string Title { get; set; }
    int Year { get; set; }
    Guid ClientID { get; set; }

    ICollection<FormField<int>> Fields { get; set; }
}

我认为我想要的是一个允许我抽象类型信息的接口,从而将集合键入为(例如)IFormField 而不是 FormField<> 的实例

但如果不在界面中强烈键入集合,我看不到如何定义它......

任何帮助(包括任何替代解决方案!)将不胜感激!

谢谢,本

I have an object (form) which contains a collection (.Fields) which I want to contain instances of a generic class (FormField).

The FormField, simply, is defined as such:

public class FormField<T>
{
    private Form Form;
    public T Value { get; set; }
    public string Name { get; set; }

    public void Process()
    {
        // do something
    }

    public FormField(Form form, string name, T value)
    {
        this.Name = name;
        this.Value = value;
        this.Form = form;
    }
}

This allows me to have FormField, FormField etc. and that part works great.
What I want is a collection of "Formfields" regardless of the type, but I am forced into defining a type (it seems) such as:

public class Form
{

    string Code { get; set; }
    string Title { get; set; }
    int Year { get; set; }
    Guid ClientID { get; set; }

    ICollection<FormField<int>> Fields { get; set; }
}

What, I think, I want is an interface that allows me to abstract the type information and thus type the collection as instances of (for exxample) IFormField not FormField<>

But I can't see how to define this without strongly typing the collection in the interface...

Any help (including any alternative solutions!) would be greatly appreciated!

Thanks, Ben

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北方的巷 2024-10-01 18:25:21

这是一些完成乔恩答案的代码:

public interface IFormField
{
    string Name { get; set; }
    object Value { get; set; }
}

public class FormField<T> : IFormField
{
    private Form Form;
    public T Value { get; set; }
    public string Name { get; set; }

    public void Process()
    {
        // do something
    }

    public FormField(Form form, string name, T value)
    {
        this.Name = name;
        this.Value = value;
        this.Form = form;
    }

    // Explicit implementation of IFormField.Value
    object IFormField.Value
    {
        get { return this.Value; }
        set { this.Value = (T)value; }
    }
}

并以您的形式:

ICollection<IFormField> Fields { get; set; }

Here's some code to complete Jon's answer:

public interface IFormField
{
    string Name { get; set; }
    object Value { get; set; }
}

public class FormField<T> : IFormField
{
    private Form Form;
    public T Value { get; set; }
    public string Name { get; set; }

    public void Process()
    {
        // do something
    }

    public FormField(Form form, string name, T value)
    {
        this.Name = name;
        this.Value = value;
        this.Form = form;
    }

    // Explicit implementation of IFormField.Value
    object IFormField.Value
    {
        get { return this.Value; }
        set { this.Value = (T)value; }
    }
}

And in your form:

ICollection<IFormField> Fields { get; set; }
夏天碎花小短裙 2024-10-01 18:25:21

创建一个非泛型接口或基类,其中可能包括 FormField 所做的所有事情, 除了特定于类型的位。然后您就可以拥有一个ICollection。显然,就所使用的字段类型而言,您将无法以强类型的方式使用它 - 但您可以使用它的所有非特定于类型的位(例如名称和形式)。

Create a non-generic interface or base class, which probably includes everything FormField does except the type-specific bits. Then you can have an ICollection<IFormField>. Obviously you won't be able to use this in a strongly-typed way, in terms of the type of field being used - but you can use all the non-type-specific bits of it (e.g. the name and the form).

也只是曾经 2024-10-01 18:25:21

另一种选择(Jon 的答案的替代方案)是应用适配器模式,在以下情况下很有用:

  • 您无法修改类型,因此无法定义基本类型为了它。
  • 或者,需要公开“特定于类型的位”(正如乔恩所说)。

当您想要公开特定于类型的位时,您可以有效必须创建一个非通用包装器。一个简短的例子:

class NonGenericWrapper<T> : IAdaptor
{
    private readonly Adaptee<T> _adaptee;

    public NonGenericWrapper(Adaptee<T> adaptee)
    {
        _adaptee = adaptee;
    }

    public object Value
    {
        get { return _adaptee.Value; }
        set { _adaptee.Value = (T) value; }
    }
}

在基类型中实现这种非通用行为将有效地打破 里氏替换原则,这就是为什么我更喜欢包装方法 我也在我的博文中争论

Another option (an alternative to Jon's answer) is to apply the adapter pattern, which can be useful when:

  • you are unable to modify the type, and can thus not define a base-type for it.
  • or, there is a need to expose 'type-specific bits' (as Jon put it).

When you want to expose type-specific bits, you effectively have to create a non-generic wrapper. A short example:

class NonGenericWrapper<T> : IAdaptor
{
    private readonly Adaptee<T> _adaptee;

    public NonGenericWrapper(Adaptee<T> adaptee)
    {
        _adaptee = adaptee;
    }

    public object Value
    {
        get { return _adaptee.Value; }
        set { _adaptee.Value = (T) value; }
    }
}

Implementing this non-generic behavior in a base-type would effectively break the Liskov substitution principle, which is why I prefer the wrapper approach as I also argue in my blog post.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文