ประเภทนี้จะต้องเป็นประเภทอ้างอิงเพื่อใช้เป็นพารามิเตอร์ 'T' ในประเภทหรือวิธีการทั่วไป


211

ตอนนี้ฉันมีสถานการณ์ที่ฉันต้องการความช่วยเหลือ ฉันพบข้อผิดพลาดในการคอมไพล์ในคลาส 'Derived' ด้านล่างตามที่แสดงในหัวเรื่อง ฉันเห็นโพสต์อื่น ๆ ที่คล้ายกับโพสต์นี้ แต่ฉันไม่เห็นความสัมพันธ์ มีคนบอกฉันว่าจะแก้ไขได้อย่างไร

using System;
using System.Collections.Generic;


namespace Example
{
    public class ViewContext
    {
        ViewContext() { }
    }

    public interface IModel
    {
    }

    public interface IView<T> where T : IModel 
    {
        ViewContext ViewContext { get; set; }
    }

    public class SomeModel : IModel
    {
        public SomeModel() { }
        public int ID { get; set; }
    }

    public class Base<T> where T : IModel
    {

        public Base(IView<T> view)
        {
        }
    }

    public class Derived<SomeModel> : Base<SomeModel> where SomeModel : IModel
    {

        public Derived(IView<SomeModel> view)
            : base(view)
        {
            SomeModel m = (SomeModel)Activator.CreateInstance(typeof(SomeModel));
            Service<SomeModel> s = new Service<SomeModel>();
            s.Work(m);
        }
    }

    public class Service<SomeModel> where SomeModel : IModel
    {
        public Service()
        {
        }

        public void Work(SomeModel m)
        {

        }
    }
}

ฉันไม่ได้รับข้อผิดพลาดในการรวบรวม
Vince Panuccio

รหัสนี้ไม่แสดงข้อผิดพลาดนั้น รวบรวมอย่างหมดจด
Marc Gravell

คำตอบ:


474

ฉันไม่สามารถทำซ้ำได้ แต่ฉันสงสัยว่าในรหัสจริงของคุณมีข้อ จำกัด บางอย่างที่T : class- คุณต้องเผยแพร่สิ่งนั้นเพื่อให้คอมไพเลอร์มีความสุขเช่น (ยากที่จะพูดอย่างแน่นอนโดยไม่มีตัวอย่างทำซ้ำ):

public class Derived<SomeModel> : Base<SomeModel> where SomeModel : class, IModel
                                                                    ^^^^^
                                                                 see this bit

12
ขอบคุณใช่นั่นแหละ เมื่อฉันเพิ่มข้อ จำกัด ของชั้นเรียนข้อผิดพลาดของการคอมไพล์ก็หายไป ต่อไปนี้ดูเหมือนว่าจะตอบสนองความต้องการประเภทการอ้างอิง
ChrisS

นี่คือสิ่งที่ทำงาน public class Base <T> โดยที่ T: class, IModel {public Base (IView <T> view) {}} คลาสสาธารณะที่ได้รับ <SomeModel>: Base <SomeModel> โดยที่ SomeModel: class, IModel {public Derived (IView <SomeModel> มุมมอง): ฐาน (มุมมอง) {SomeModel m = (SomeModel) Activator.CreateInstance (typeof (SomeModel)); บริการ <SomeModel> s = new Service <SomeModel> (); s.Work (m); }}
ChrisS

มีประโยชน์เช่นกัน :) ขอบคุณ :) ในฐานะที่เป็นด้านข้างฉันคิดว่าเราไม่ควรคัดลอก constrait เดิมซ้ำแล้วซ้ำอีกถ้ามันถูกใช้ในอินเตอร์เฟสแล้ว IMO
Celdor


9

ถ้าคุณใส่ข้อ จำกัด ในคลาสหรือวิธีทั่วไปคลาสหรือวิธีทั่วไปอื่น ๆ ทุกตัวที่ใช้จะต้องมีข้อ จำกัด เหล่านั้น "อย่างน้อย"

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.