如何在c#中使用接口的泛型方法?得到错误

时间:2018-02-28 01:31:34

标签: c# inheritance polymorphism

我有两种方法的接口,

我正在尝试创建通用接口INewReleaseValidationRule,其中T:INewReleaseValidationEntity将具有Run()方法。

然后我有另一个类ValidationClass,它继承了NewReleaseValidationEntityBase类。我试图调用SomeOtherClass中的ValidateInputMethod()中的Run()方法。但是我收到了错误,

**无法从System.Collections.Generic.List转换为System.Collections.Generic.IList ** SalesForecastViewModel是INewReleaseValidationEntity的间接派生类,因此根据运行时多态性它应该有效吗?

public interface INewReleaseValidationRule<T> where T : INewReleaseValidationEntity
{
    void Run(CtxNewRelease ctx, IList<T> entities);
    string GetMessage(string messageName, string fallbackMessage);
}

public interface INewReleaseValidationEntity
{
    string GetDefaultSkipMsg();
    List<ValidationError> ValidationErrors {get;set;}
    bool Valid { get; set; }
    void SetValidation(string errorCode, string errorMessage, string errorField, Severities severity);
    }

public abstract class NewReleaseValidationEntityBase : INewReleaseValidationEntity
{

    public NewReleaseValidationEntityBase()
    {
        Valid = true;
    }
 //Implementation all the methods of INewReleaseValidationEntity 
}


public class ValidationClass : NewReleaseValidationEntityBase
{
    public ValidationClass()
    {
        MessageHelper.LoadToCache(TYPECODE);
    }

    public string GetMessage(string messageName, string fallbackMessage)
    {
        return MessageHelper.TryGetFromCache(messageName, fallbackMessage);
    }

    public void Run(Context.CtxNewRelease context, IList<INewReleaseValidationEntity> sList)
    {
       //Some code statement to perform validation
    }
}

然后我查看了继承的模型类,

public class SalesForecastViewModel : NewReleaseValidationEntityBase
{
   //Some properties and functions
}

然后在另一个类中,我试图调用泛型方法Run(),

Public Class SomeOtherClass {
     public void ValidateInput(List<SalesForecastViewModel> viewModel)
    {

            ValidationClass vcObject = new ValidationClass();
            **vcObject.Run(context, viewModel);**  //Here viewModel is of child class. It should convert it runtime.

        }
    }

}

//对于长期混乱的代码感到抱歉。

1 个答案:

答案 0 :(得分:1)

您面临的问题是由IList<T>界面不协变这一事实引起的。这真正意味着,IList<ParentType>无法分配给IList<ChildType>的实例。该文档将帮助您更多地了解该主题。

所以你可以在这里走两条路:

  1. 使用数组从隐式引用转换中受益。这里的代码如下:

    vsObject.Run(context, viewModel.ToArray());

  2. 切换到代码中的IEnumerable<T>的协变接口。因此,这将要求您更改ValidationClass.Run方法的签名,如下所示:

    void Run(CtxNewRelease ctx, IEnumerable<T> entities)

  3. 这会使传递的List<SalesForecastViewModel>可分配给IEnumerable<INewReleaseValidationEntity>类型的变量。

    希望这有帮助。