委托 - 对代表的使用是否正确?

时间:2010-10-21 00:02:17

标签: c# delegates mapping

我创建了一个类,其中主要任务是从数据库获取数据并将其映射到某个对象。问题是同一个类需要将不同的datareader映射到不同的对象。所以,我试图做的是使用委托来获取映射方法。

这是我的代码的一部分。以粗体显示重要的行。

public class GetDetails<T>
{       
    **public delegate void DelegateMapping(T position, IDataReader reader);**
    **public DelegateMapping mappingMethod;**

    public T Get(T instance)
    {
        //Get IDs and Add to list
        _db.ExecuteReader(storedProcedure.ToString(), CommandType.StoredProcedure, reader =>
        {
            while ( reader.Read() )
            {
                **mappingMethod(instance, reader);**
            }

        }, parameterList.ToArray());

        return instance;
    }
}

这是调用和使用“GetDetails”类

的类
public class PositionDB : DbBase
{
    public Position GetPositionDetails(string IDs)
    {
        GetDetails<Position> getIDs = new GetDetails<Position>(base.db);
        getIDs.storedProcedure = StoredProcedure.NET_ADM_GetPositionDetails;

        //Set the Delegated Method
        **getIDs.mappingMethod = MappingPositionDetails;**

        //Set Parameters
        getIDs.parameterList.AddInParam("PositionIds", DbType.String, IDs);

        //Return the PositionId Collection
        return getIDs.Get(new Position());
    }

    **private void MappingPositionDetails(Position position, IDataReader reader)
    {
        position.Id = reader["CompPositionId"];
        position.Description = reader["Description"];
        position.ExpirationDate = reader["ExpirationDate"];
        position.Title = reader["Title"];
    }**

}

代码工作正常。

问题是:

  1. 我是否正确使用了委托?
  2. 这种解决方案将来会导致问题(性能)吗?
  3. 还有另一个更好的解决方案吗?
  4. 非常感谢

    塞巴斯蒂安

2 个答案:

答案 0 :(得分:1)

专门回答您的问题:

  1. 是的,您确实正确使用了代理
  2. 是的,由于多线程时出现并发问题,可能会导致问题
  3. 我想是的,我在下面详细介绍了一个可能的解决方案
  4. 我建议进行三项修改:

    1. 将委托调用移动到方法中(并发问题,一个线程可以更改映射委托,而另一个线程尝试访问它,现在尝试将读取器映射到与提供的完全不同的对象)。
    2. 使用已经存在的通用Action / Func委托,无需定义自己的。
    3. 使用lambda表达式定义映射,不需要额外的方法
    4. 注意:2和3至少需要.net 3.5。

      使用这两个提案,您的代码将如下所示:

      public class GetDetails<T>
      {       
          public T Get (T instance, Action<T, IDataReader> mappingMethod)
          {
              //Get IDs and Add to list
              _db.ExecuteReader(storedProcedure.ToString(), CommandType.StoredProcedure, reader =>
              {
                  while ( reader.Read() )
                  {
                      mappingMethod(instance, reader);
                  }
      
              }, parameterList.ToArray());
      
              return instance;
          }
      }
      

      现在您也可以在多线程环境中使用此方法。

      修改

      刚刚意识到它只是代码的一部分。我更正了我的建议,将其考虑在内。

答案 1 :(得分:0)

  1. 是(你可以做一些改进,见3)
  2. 性能不明智,可能存在发现问题。
  3. 我会使用多态来完全消除委托以获得不公正性。也许使用抽象方法/类。另外,根据您正在开发的.NET版本,您可以使用lambdas和更简单的类型。
  4. public Action<Position, IDataReader> Mapping { get; set; }

    然后

    getIDs.Mapping = (position, reader) => 
        {
            position.Id = reader["CompPositionId"];
            position.Description = reader["Description"];
            position.ExpirationDate = reader["ExpirationDate"];
            position.Title = reader["Title"];
        };