介绍

马克·格雷韦尔(Marc Gravell)的建议提示了这个问题,我将新的语言功能建议发布到此站点上,以收集关于它们的一般意见。

想法是收集他们是否会有所帮助,或者是否已经有另一种方式来实现我所追求的目标。

建议(受限类型)

因此,在VB.Net中编写了一个普通的变量声明:

Dim SomeVariable as SomeType

我建议允许以下形式
Dim SomeVariable1 as {SomeType, ISomeInterface}
Dim SomeVariable2 as {SomeType, ISomeInterface, ISomeOtherInterface}

该语法是从Vb.Net约束泛型的样式中借用的

为什么要允许它?...这有什么用?

好吧,我最初想到的具体案例是定义控件的特定子集。
我希望为一系列Control工厂创建一个界面,该界面将根据一些业务规则提供控件。

这些控件的使用者将需要通过该接口(interface)创建的所有控件还应该实现一系列的接口(interface)(在我的情况下仅为一个),这为所有这些控件提供了通常控件中通常没有的其他功能。

值得注意的是,以下当前无效。
Public Interface ISpecialControl
End Interface

Public Interface IControlProvider
    Function CreateControl(Of T As {Control, ISpecialControl})() As T
End Interface

Public Class SpecialTextBoxProvider
    Implements IControlProvider
    Public Function CreateControl(Of T As {Control, ISpecialControl})() As T Implements IControlProvider.CreateControl
        Return New SpecialTextBox
    End Function
End Class

Public Class SpecialTextBox
    Inherits TextBox
    Implements ISpecialControl
    Public Sub New()

    End Sub
End Class

我认为这可以转换为C#:
public interface ISpecialControl
{
}

public interface IControlProvider
{
    T CreateControl<T>()
        where T : Control, ISpecialControl;
}

public class SpecialTextBoxProvider : IControlProvider
{
    public T CreateControl<T>()
        where T : Control, ISpecialControl
    {
        return new SpecialTextBox();
    }
}

public class SpecialTextBox : TextBox, ISpecialControl
{
}

由于无法将SpecialTextbox强制转换为T,因此尝试返回“New SpecialTextbox”失败。
"Value of type 'MyApp.SpecialTextBox' cannot be converted to 'T'"

我意识到我的工厂可以被允许返回简单的控件,并且可以在运行时检查它们是否实现了ISpecialControl,但这会产生运行时问题,我宁愿在编译时进行检查,因为这是逻辑上的可能性,即使当前尚不可行。

更新:想法是这些工厂可以位于外部(也许甚至是第三方)程序集中,并且可以依赖于他们想要的任何控件库,从而创建和返回也实现了ISpecialControl的这些控件的派生类。

这些程序集可以通过自我配置反射(首先通过反射,然后进行配置,然后在以后的运行中使用)进行定位,并且在调用程序集不知道这些控件将采取何种依赖性的情况下使用。

确实要求这些工厂是可构造的,而无需传递有关它们预期要调用的控件的信息,因为这会破坏重点。

那么,您如何看待……这会有用吗?……是否有更好的方法来实现这一目标?已经有办法实现这一目标了吗?

最佳答案

我认为,虽然表面上有用,但最好通过以下两种方法之一来处理:

  • Duck通过动态键入(VS2010中提供),尽管消除了类型安全性,但仍具有更大的灵活性。
  • 通用组成

  • 您最初的示例不需要任何内容​​,并且可以像下面这样轻松地工作:
    public interface IControlProvider<T>
        where T : Control, ISpecialControl
    {
        T CreateControl();
    }
    
    public class SpecialTextBoxProvider : IControlProvider<SpecialTextBox>
    {
        public SpecialTextBox CreateControl()
        {
            return new SpecialTextBox();
        }
    }
    

    实际上,鉴于大多数控件都有默认的公共(public)构造函数,因此您可以使其变得更加容易:
    public class ControlProvider : IControlProvider<T>
        where T : Control, ISpecialControl, new()
    {
        public T CreateControl()
        {
            return new T();
        }
    }
    
    var control = ControlProvider<SpecialTextBox>.CreateControl();
    

    考虑到对调用代码的其他限制,即不直接引用SpecialTextBox的引用依赖项,这将无法正常工作。

    关于c# - "Constrained Types"在VB/C#中有用吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/553046/

    10-10 16:24