Jenis harus merupakan jenis referensi untuk menggunakannya sebagai parameter 'T' dalam jenis atau metode umum

211

Saya semakin dalam ke obat generik dan sekarang memiliki situasi yang saya perlu bantuan. Saya mendapatkan kesalahan kompilasi pada kelas 'Berasal' di bawah ini seperti yang ditunjukkan pada judul subjek. Saya melihat banyak posting lain yang mirip dengan ini tetapi saya tidak melihat hubungan. Bisakah seseorang memberi tahu saya cara mengatasi ini?

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)
        {

        }
    }
}
ChrisS
sumber
Saya tidak mendapatkan kesalahan kompilasi
Vince Panuccio
Kode ini tidak menunjukkan kesalahan itu. Kompilasi dengan bersih.
Marc Gravell

Jawaban:

474

Saya tidak dapat repro, tetapi saya menduga bahwa dalam kode aktual Anda ada batasan di suatu tempat yang T : class- Anda perlu menyebarkannya untuk membuat kompiler bahagia, misalnya (sulit untuk mengatakan dengan pasti tanpa contoh repro):

public class Derived<SomeModel> : Base<SomeModel> where SomeModel : class, IModel
                                                                    ^^^^^
                                                                 see this bit
Marc Gravell
sumber
12
Terima kasih ya itu saja. Setelah saya menambahkan batasan kelas kesalahan kompilasi hilang. Berikut ini tampaknya memuaskan kebutuhan akan tipe referensi.
ChrisS
Inilah yang berhasil. Basis kelas publik <T> di mana T: kelas, IModel {public Base (IView <T> view) {}} kelas publik Berasal <SomeModel>: Basis <SomeModel> di mana SomeModel: class, IModel {public Turun (IView <SomeModel> view): base (view) {SomeModel m = (SomeModel) Activator.CreateInstance (typeof (SomeModel)); Layanan <SomeModel> s = Layanan baru <SomeModel> (); s.Bekerja (m); }}
ChrisS
Membantu juga :) Terima kasih :) Sebagai catatan tambahan, saya pikir kita tidak boleh menyalin konstipasi yang sama lagi dan lagi jika sudah diterapkan dalam antarmuka, IMO.
Celdor
46

Anda mendapatkan kesalahan ini jika Anda terpaksa Tmenjadi seorangclass

terima kasih
sumber
9

Jika Anda meletakkan batasan pada kelas atau metode umum, setiap kelas umum atau metode lain yang menggunakannya harus memiliki "setidaknya" batasan tersebut.

Guish
sumber