Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在抽象基类中定义泛型转换器方法_C#_Generics - Fatal编程技术网

C# 在抽象基类中定义泛型转换器方法

C# 在抽象基类中定义泛型转换器方法,c#,generics,C#,Generics,我的逻辑对象有一个通用抽象基类,基本上如下所示: public abstract class LogicClass<TDal> where TDal : DataClass, new() { protected TDal _dalObj; protected LogicClass(TDal dalObj) { _dalObj = dalObj; } // basic properties and default methods for va

我的逻辑对象有一个通用抽象基类,基本上如下所示:

public abstract class LogicClass<TDal>
    where TDal : DataClass, new()
{
    protected TDal _dalObj;

    protected LogicClass(TDal dalObj)
    { _dalObj = dalObj; }

    // basic properties and default methods for validating, deleting etc.
}
    protected static List<T> GetList<T>(string whereStatement)
        where T : LogicClass<TDal>, new()
    {
        var dalObjList = DataManager.GetCollection<TDal>(whereStatement);
        return dalObjList.ConvertAll(dalObj => new T() { _dalObj = dalObj });
    }
    protected abstract Converter<TDal, LogicClass<TDal>> DalConverter;
公共抽象类LogicClass
其中TDal:DataClass,new()
{
受保护的TDal_dalObj;
受保护逻辑类(TDal dalObj)
{{u dalObj=dalObj;}
//验证、删除等的基本属性和默认方法。
}
其中有几个静态方法,用于使用我自己的ORM获取数据。它们看起来像这样:

public abstract class LogicClass<TDal>
    where TDal : DataClass, new()
{
    protected TDal _dalObj;

    protected LogicClass(TDal dalObj)
    { _dalObj = dalObj; }

    // basic properties and default methods for validating, deleting etc.
}
    protected static List<T> GetList<T>(string whereStatement)
        where T : LogicClass<TDal>, new()
    {
        var dalObjList = DataManager.GetCollection<TDal>(whereStatement);
        return dalObjList.ConvertAll(dalObj => new T() { _dalObj = dalObj });
    }
    protected abstract Converter<TDal, LogicClass<TDal>> DalConverter;
受保护的静态列表GetList(字符串语句)
其中T:LogicClass,new()
{
var dalObjList=DataManager.GetCollection(whereStatement);
返回dalObjList.ConvertAll(dalObj=>newt(){u dalObj=dalObj});
}
大多数情况下都能很好地工作,但问题是使用默认构造函数,然后设置数据对象,因为在创建数据时,在子类中使用无参数构造函数来设置默认属性(例如,在添加客户机对象时,国家设置为默认国家)

由于我也不能将ctor与使用泛型约束的参数一起使用,因此我想到了以下解决方案:

    protected static List<T> GetListT>(Converter<TDal, T> creator, string whereStatement)
        where T : LogicClass<TDal>
    {
        var dalObjList = DataManager.GetCollection<TDal>(whereStatement);
        return dalObjList.ConvertAll<T>(creator);
    }
受保护的静态列表GetListT>(转换器创建者,字符串语句)
其中T:LogicClass
{
var dalObjList=DataManager.GetCollection(whereStatement);
返回dalObjList.ConvertAll(创建者);
}
这是可行的,但我需要多次使用这个转换器,不想多次传递它

所以我的问题是,有没有办法只定义一次通用转换器

我想到了这样的事情:

public abstract class LogicClass<TDal>
    where TDal : DataClass, new()
{
    protected TDal _dalObj;

    protected LogicClass(TDal dalObj)
    { _dalObj = dalObj; }

    // basic properties and default methods for validating, deleting etc.
}
    protected static List<T> GetList<T>(string whereStatement)
        where T : LogicClass<TDal>, new()
    {
        var dalObjList = DataManager.GetCollection<TDal>(whereStatement);
        return dalObjList.ConvertAll(dalObj => new T() { _dalObj = dalObj });
    }
    protected abstract Converter<TDal, LogicClass<TDal>> DalConverter;
受保护的抽象转换器DalConverter;
。。但是让它静止更合理,这样我就不能再让它抽象了

我可以编一本
字典
,但我担心这会带来性能损失


有什么想法吗?

您可以将转换器放入泛型类中的静态变量中,并在程序启动时对其初始化一次

泛型类为泛型类型参数的每个组合生成一个新类型,并且生成的每个类型都有一组独立的静态变量。这意味着
StaticConverter.Converter
StaticConverter.Converter

    class StaticConverter<TDal, T>
        where T : LogicClass<TDal>
    {
        public static Converter<TDal, T> Converter;
    }
类静态转换器
其中T:LogicClass
{
公共静止变流器;
}
类似于上面的类可以在代码中用于检索任何类型集的转换器。类似于
返回dalObjList.ConvertAll(StaticConverter.Converter)

必须为要使用它转换的每个类型初始化它(除非您有一些通用的转换代码,否则您可以在静态类中通用地定义转换器)

初始化如下所示,需要执行一次。由于变量是静态的,因此在程序结束之前,这些值将一直保留

 StaticConverter<User, UserLogic>.Converter = v => new UserLogic();
 StaticConverter<Client, ClientLogic>.Converter = v => new ClientLogic("Brazil");
StaticConverter.Converter=v=>newuserlogic();
StaticConverter.Converter=v=>newclientlogic(“巴西”);

编辑

您可以创建一个默认转换器,如下所示。这为转换器定义了一个默认值,您可以为要自定义的转换器覆盖该值

现在,您可以确保为所有类型设置了转换器,但仅为与默认类型不同的类型提供更新的转换器

    public static T GetLogic<TDal, T>(TDal item)
    {
        return default(T);
    }

    class StaticConverter<TDal, T>
        where T : LogicClass<TDal>
    {
        public static Converter<TDal, T> Converter = c => GetLogic<TDal, T>(c);
    }
publicstatict GetLogic(TDal项)
{
返回默认值(T);
}
类静态转换器
其中T:LogicClass
{
公共静态转换器=c=>GetLogic(c);
}

那太酷了!唯一的缺点是不知道是否每个转换器都已设置。我想我必须在每个子类中将转换器定义为一个静态字段,并将其传递给其他子类,因为我认为没有其他方法可以确保所有内容都在编译时工作。我仍然会将这个答案标记为已接受,因为我认为这是你能得到的最接近的答案:)谢谢。我提供了一个编辑,显示了如何创建默认值,以便确保任何转换器至少有一个默认值。