سؤال

ربما أنا غبية ولكن...

أملك:

public interface IRequest
{
    IList<IRequestDetail> Details { get; set; }

    // stuff
}

public interface IRequestDetail
{
    // stuff
}

ثم لدي:

public class MyRequest : IRequest
{
    IList<MyRequestDetail> Details {get; set; }

    // stuff
}

public class MyRequestDetail : IRequestDetail
{
    // stuff
}

لا يعمل.

تغضب C# مني لأن MyRequest لا يطبق الواجهة بسبب عدم وجود قائمة IRequestDetail.

الآن إذا قمت بتغييرها بحيث تكون التفاصيل هي IList of IRequestDetail، فسأضطر إلى إرسالها إلى MyRequestDetail في كل مكان في الكود الذي أستخدم فيه عضوًا غير واجهة (لدي العديد من الطلبات التي تشترك في أشياء مشتركة، ولكنها متخصصة بعد ذلك).

أفهم نوعًا ما سبب الخطأ، لكن ليس تمامًا!

هل كانت مفيدة؟

المحلول

أعتقد، بناءً على سؤال أن المشكلة تكمن في أنك تريد التعامل مع التفاصيل كقائمة عامة وفرض أنها تنفذ IRequestDetail.تريد أيضًا أن تتم كتابته بشكل أكثر تحديدًا لفئات التنفيذ.في هذه الحالة، تحتاج إلى جعل IRequest عامًا.

جرب هذا:

public interface IRequest<T> where T : IRequestDetail
{
    IList<T> Details { get; set; }

    // stuff
}

public class MyRequest : IRequest<MyRequestDetail>
{
    public IList<MyRequestDetail> Details {get; set; }

    // stuff
}

هذا يجب أن تعمل من أجلك.

تحرير 2017-03-17

ردًا على تعليق @Robert، راجع الكود الموسع أدناه:

public interface IRequestDetail
{

}

public class MyRequestDetail : IRequestDetail
{

}

public interface IRequest<T> where T : IRequestDetail
{
    IList<T> Details { get; set; }

    // stuff
}

public class MyRequest<T> : IRequest<T>
    where T : IRequestDetail
{
    public IList<T> Details { get; set; }

    // stuff
}

public class Consumer
{
    public void MyFunction<T>(IRequest<T> request)
        where T : IRequestDetail
    {

    }

    public void Foo()
    {
        var test = new MyRequest<MyRequestDetail>();
        MyFunction(test);
    }
}

نصائح أخرى

وتطابق. مايكل لديه الحل. المشكلة هي اصعب قليلا.

وعلى أنه لا يوجد تحويل صريح من

IList<MyRequestDetail>

إلى

IList<IRequestDetail>

ولأن ذلك يعني ضمنا أنه يمكنك إضافة كائنات أخرى، التي تستند إلى فئات مختلفة (على سبيل المثال MyRequestDetail2)، التي ليست "MyRequestDetail" إلى كائن الثاني. وهذا سيكون غير قانوني للمرة الأولى.

وهذا يرجع إلى لاتباين وتباين مرافق وتباين معاكس في C # هذا. هناك مفصل جدا، كسبلايناتيون واضح جدا من القضايا (تقسيم إلى أجزاء كثيرة) على <لأ href = "http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx" يختلط = "نوفولو noreferrer"> اريك ليبرت مدونة .

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top