代码之家  ›  专栏  ›  技术社区  ›  Dav

作为属性的非构造泛型(例如List<T>)

  •  1
  • Dav  · 技术社区  · 14 年前

    问题

    BaseGridView<T> : DataGridView where T : class . 基于 BaseGridView (例如 InvoiceGridView : BaseGridView<Invoice> )稍后在应用程序中使用,以使用提供的共享功能显示不同的业务对象 基本网格视图 (如虚拟模式、按钮等)。

    现在有必要创建一个用户控件来引用那些构造的类型来控制一些 共享 功能(如过滤) . 因此,我希望在用户控件上创建一个公共属性,使我能够将它附加到任何 在设计器/代码中: public BaseGridView<T> MyGridView { get; set; } . 问题是,它不起作用:-)编译时,我得到以下消息:

    找不到类型或命名空间名称“T”(是否缺少using指令或程序集引用?)

    我意识到我可以把共享的功能提取到一个接口上,马克 基本网格视图

    但我很好奇是否有一些神秘的C#命令/语法可以帮助我实现我想要的-而不会用我并不真正需要的接口污染我的解决方案:-)

    BaseGridView<object> MyGridView { get; set; } ,和。。。答案仍然不是: .

    好吧,因为协方差只在接口上受支持,所以我承认失败并定义了一个接口(只显示了其中的一部分):

    public interface IBaseGridView<out T> where T : class
    {
        bool ScrollTo(Predicate<T> criteria);
        bool ScrollTo(T object);
    }
    

    我现在可以投出我的爱人了 InvoiceGridView IBaseGridView<object> - ScrollTo 给我的编译带来了麻烦:

    无效差异:类型参数“T”在“GeParts.Controls.IBaseGridView.ScrollTo(T)”上必须相反有效T是协变的。

    ScrollTo(object o) -这并不理想,但却完成了任务。令我吃惊的是,编译器抱怨第二个问题 滚动到 实例 一个 out T ,但使用类型本身(例如 Predicate<T> )你没事吧?似乎很挑剔。。。

    5 回复  |  直到 4 年前
        1
  •  1
  •   hawk    14 年前

    自从你写了

    但我很好奇,是否有一些神秘的C#命令/语法可以帮助我实现我想要的

    我想补充一点,C#4.0使使用<替代派生类型来替代基类型成为可能;输出T>求协方差。所以你可以

    公共BaseGridView< &燃气轮机;MyGridView{get;集合;}

        2
  •  1
  •   Peter Ruderman    14 年前

    例如:

    public BaseGridView<T> GetMyGridView<T>() { ... }
    public void SetMyGridView<T>(T gridView) { ... }
    

    class MyClass<T> {
        public BaseGridView<T> MyGridView { get; set; }
    }
    
        3
  •  0
  •   JSBÕ±Õ¸Õ£Õ¹    14 年前

    public BaseGridView<T> MyGridView<T> { get; set; }
    

    原始答案的问题是类型参数必须出现在方法或类声明上,而不仅仅是返回值上。

    请注意,编译器无法从返回值推断泛型类型,因此需要指定 T MyGridView .

        4
  •  0
  •   Adam Houldsworth    14 年前

    我只是试着拼凑一些代码,对我来说效果很好:

        public class A<T> where T : class
        {
            public virtual A<T> ARef
            {
                get { return default(A<T>); }
            }
        }
    
        public class B : A<B>
        {
            public override A<B> ARef
            {
                get
                {
                    return base.ARef;
                }
            }
        }
    
        5
  •  0
  •   EricSchaefer    14 年前

    public BaseGridView MyGridView{get;集合;}

    public BaseGridView<T> GetMyGridView<T> { return whatever; }
    public void SetMyGridView<T>( BaseGridView<T> bgv) { whatever = bgv; }
    

    ??

    已编辑。Matthew是对的,属性可能不是泛型的。你必须使用getter/setter。