约束违规,列表<model <type1>&gt;列出<model <type2>&gt;

时间:2017-09-07 08:30:46

标签: c# generics system.reflection

我会尽力解释这一点。

转换:

Source type:      List<ConfigurationProcessFilterModel<SqlDbAccess>>
Destination type: List<ConfigurationProcessFilterModel<SQLiteDbAccess>>

类型定义:

abstract class BaseEntityModel<T> : INotifyPropertyChanged where T : IDbAccess
class ConfigurationProcessFilterModel<T> : BaseEntityModel<T> where T : IDbAccess
class SqlDbAccess : SQLBase, IDbAccess
class SQLiteDbAccess : SQLBase, IDbAccess
abstract class SQLBase
interface IDbAccess

我想达到什么目的:

将类型为SqlDbAccess的模型列表转换为SQLiteDbAccess,反之亦然。

ModelConverter:

public class ModelConverter<TS, TD>
    where TS : SQLBase, IDbAccess
    where TD : SQLBase, IDbAccess
{
    public static TDest Convert<TSource, TDest>(object source)
        where TSource : List<BaseEntityModel<TS>>, new()
        where TDest : List<BaseEntityModel<TD>>, new()
    {
        var sourceModel = (TSource)source;
        var destModel = new TDest();
        var destInnerType = typeof(TDest).GetType().GetGenericArguments()[0];

        foreach (var sourceItem in sourceModel)
        {
            var destItem = (BaseEntityModel<TD>)Activator.CreateInstance(destInnerType);
            destModel.Add(destItem);
        }

        return destModel;
    }
}

呼叫者:

if (property.PropertyType.IsEnumerable())
{
    var innerType =
        property.PropertyType.GetGenericArguments()[0].GetGenericArguments()[0];
    if(innerType == typeof(SqlDbAccess))
    {
        //List<BaseEntityModel<SqlDbAccess>>
        var sourceType = property.PropertyType;
        var sourceModelType = sourceType.GetGenericArguments()[0];

        //List<BaseEntityModel<SQLiteDbAccess>>
        var destinationModelType = sourceModelType.GetGenericTypeDefinition()
            .MakeGenericType(typeof(SQLiteDbAccess));
        var destinationType = typeof(List<>)
            .MakeGenericType(destinationModelType);

        var method = typeof(ModelConverter<SqlDbAccess, SQLiteDbAccess>)
            .GetMethod("Convert");
        var generic = method.MakeGenericMethod(sourceType, destinationType);
        model = generic.Invoke(this, new object[] { model });
    }
}

错误:

  

System.ArgumentException:'GenericArguments [0],'System.Collections.Generic.List 1[Data.Models.ConfigurationProcessFilterModel 1 [Data.Database.SqlDbAccess]]','TDest ConvertTSource,TDest'违反了类型'的约束TSource ''

     

内部例外:
  VerificationException:Method Data.ModelConverter 2[Data.Database.SqlDbAccess,Data.Database.SQLiteDbAccess].Convert: type argument 'System.Collections.Generic.List 1 [Data.Models.ConfigurationProcessFilterModel`1 [Data.Database.SqlDbAccess]]'违反了类型参数'TSource'的约束。

1 个答案:

答案 0 :(得分:1)

解决了以下定义:

    public static TDest Convert<TSource, TDest, TS1, TS2>(object source) where TSource : List<TS1>, new() where TDest : List<TS2>, new() where TS1 : BaseEntityModel<TS> where TS2 : BaseEntityModel<TD>