C# 我可以用泛型类型解决这个问题吗?

C# 我可以用泛型类型解决这个问题吗?,c#,generics,C#,Generics,下面是我想要的班级结构: public class AllocationNEW<TActivity, TResource> where TActivity : AllocatableActivity<TActivity> where TResource : AllocatableResource<TResource> { public TResource Resource { get; private set; } pu

下面是我想要的班级结构:

  public class AllocationNEW<TActivity, TResource> 
    where TActivity : AllocatableActivity<TActivity>
    where TResource : AllocatableResource<TResource>
  {

   public TResource Resource { get; private set; }
   public TActivity Activity { get; private set; }
   public TimeQuantity Period { get; private set; }

   public AllocationNEW(TResource resource, TActivity activity, DateTime eventDate, TimeQuantity timeSpent)
    {
        Check.RequireNotNull<IResource>(resource);
        Resource = resource;

        Check.RequireNotNull<Activities.Activity>(activity);
        Activity = activity;

        Check.Require(timeSpent.Amount >= 0, Msgs.Allocation_NegativeTimeSpent);
        TimeSpentPeriod = _toTimeSpentPeriod(eventDate, timeSpent);
    }
   }


public class AllocatableResource<TResource>
{
    public string Description { get; protected set; }
    public string BusinessId { get; protected set; }     
}

public class AllocatableActivity<TActivity>
{

    public string Description { get; protected set; }
    public string BusinessId { get; protected set; }

    protected readonly IDictionary<DateTime, Allocation<TActivity, TResource>> _allocations;

    public virtual void ClockIn<TResource>(DateTime eventDate, TResource resource, TimeQuantity timeSpent)
    {
        var entry = new Allocation<TActivity, TResource>(resource, this, eventDate, timeSpent);
        if (_allocations.ContainsKey(eventDate))
        {
            Check.Require(_allocations[eventDate].Resource.Equals(resource),
                          "This method requires that the same resource is the resource in this allocation.");
            _allocations[eventDate] = entry;
        }
        else _allocations.Add(eventDate, entry);
    }
}
公共类分配新建
其中触觉:AllocatableActivity
其中TResource:AllocatableResource
{
public TResource资源{get;private set;}
公共触觉活动{get;private set;}
公共时间量周期{get;private set;}
公共分配新建(TResource资源、战术活动、日期时间事件日期、时间数量时间支出)
{
检查。要求完整(资源);
资源=资源;
检查。要求完整(活动);
活动=活动;
检查要求(TimeSpunt.Amount>=0,Msgs.Allocation\u NegativeTimeSpunt);
TimePentPeriod=_toTimeSpentPeriod(事件日期,TimePent);
}
}
公共类可分配资源
{
公共字符串说明{get;protected set;}
公共字符串BusinessId{get;protected set;}
}
公共类可分配活动
{
公共字符串说明{get;protected set;}
公共字符串BusinessId{get;protected set;}
受保护的只读IDictionary\u分配;
公共虚拟void时钟(DateTime eventDate、TResource资源、TimeQuantity timespunt)
{
var条目=新分配(资源、此、事件日期、时间支出);
如果(_allocations.ContainsKey(eventDate))
{
检查.Require(_分配[eventDate].Resource.Equals(资源),
“此方法要求相同的资源是此分配中的资源。”);
_分配[eventDate]=条目;
}
else\u allocations.Add(事件日期,条目);
}
}
当然,AllocatableActivity就是这个方案出现故障的地方。我需要在这个类中使用一个分配集合,但在客户端使用ClockIn方法之前,我不知道TResource将是什么

关于如何使用资源和活动类型来解决分配类,我一直有各种各样的想法,所以我希望我遗漏了一些明显的东西。似乎它应该可以用泛型来解决

干杯

更多信息 以下是一些活动示例:

public class ProjectActivity : AllocatableActivity<Project>
{
    public ProjectActivity(Project project) {
        _project = project;
        Description = _project.Description;
        BusinessId = _project.Code.ToString();
    }
    // private readonly Project _project; --> shouldn't need anymore
}

public class AccountingActivity : AllocatableActivity<Account>
{

    public AccountingActivity(Account account)
    {
        _account = account;
        Description = account.Description;
        BusinessId = account.AccountId;
    }
    // private readonly Account _account;
}
公共类项目活动:AllocatableActivity
{
公共项目活动(项目){
_项目=项目;
Description=\u project.Description;
BusinessId=_project.Code.ToString();
}
//私有只读项目-->不应该再需要了
}
公共类AccountingActivity:可分配活动
{
公共会计活动(账户)
{
_账户=账户;
描述=账户描述;
BusinessId=account.AccountId;
}
//私人只读账户(U账户);;
}
以下是一个资源示例:

public class StaffMemberResource : AllocatableResource<StaffMember>
{
    public StaffMemberResource(StaffMember staffMember) {
        Description = staffMember.Name.ToString();
        BusinessId = staffMember.Number;
    }
}
公共类StaffMemberResource:AllocatableResource
{
公共StaffMemberResource(StaffMember StaffMember){
Description=staffMember.Name.ToString();
BusinessId=staffMember.Number;
}
}
数据输入将由单个资源完成。我还不知道递归问题,但除创建活动的成本外,在数据输入会话中不知道TResource的原因没有其他商业原因(目前有大约300个基础项目和帐户的组合,我希望将其视为可分配活动)

报告将涉及多个资源(即,需要在花费的时间上签字的经理需要查看其分配的资源花费的所有时间,按项目的临时报告等)


我在没有泛型(接口和基类)的情况下阐述了这一点但是在涉及类型时有一些尴尬,所以我想看看泛型是否会使界面更简单。

为什么
AllocatableActivity
TResource
中不也是泛型的?这将使它在语言方面都能工作-这有业务问题吗?你能举个
Tactivii的例子吗ty
TResource
,为什么创建活动时您可能不知道需要什么样的资源?

为什么
AllocatableActivity
TResource
中不也是通用的?这将使它在语言方面都能正常工作-这有业务问题吗?您能给出
tractivii的示例吗ty
TResource
,以及为什么在创建活动时您可能不知道您需要什么样的资源?

虽然还不完全清楚您想要完成什么,但这是我所看到的一般意义

您拥有将用于
tractivity
TResource
的现有(或新)业务对象。您的
AllocatableActivity
类表示一个
tractivity
,其中包含一个
TResource
的多个实例(可能是不同的类型)

另一方面,您有一个
AllocationNEW
类,它表示一个
AllocatableActivity
和一个
AllocatableResource
(可以说是硬币的另一面)。这是一个单活动资源关联类

您拥有的与关系数据库中的多个关系非常相似。您拥有活动、资源,并且有一个允许您链接它们的活动资源表

如果不使用反射,我看不到任何一个解决方案支持所有这些功能(我也看不出在这种情况下会得到什么)。您可能需要的是为
AllocationNEW
提供一个非通用的抽象基类,它将资源的属性公开为公共基类(即使最接近的对象是
对象
),也要让泛型实现继承并公开它自己的强类型属性(或者,为了“更干净”的方法,让它用强类型版本替换父弱类型属性)
public abstract class Resource
{
    public string Description { get; }
}

public class AllocatableResource<TResource> where TResource : Resource
{
    ...
}

public abstract class Allocation<TActivity>
{
    protected Allocation(
        Resource resource, TActivity activity, TimeQuantity period)
    {
        this.Resource = resource;
        this.Activity = activity;
        this.Period = period;
    }

    public virtual Resource Resource { get; protected set; }
    public TActivity Activity { get; protected set; }
    public TimeQuantity Period { get; protected set; }
}

public class Allocation<TActivity, TResource> : Allocation<TActivity>
    where TActivity : AllocatableActivity<TActivity>
    where TResource : AllocatableResource<TResource>
{
    public new TResource Resource { get; private set; }

    public Allocation(
        TResource resource, TActivity activity, DateTime eventDate,
        TimeQuantity timeSpent)
        : base(resource, activity, timeSpent)
    {
        ...
    }
}
public class AllocatableActivity<TActivity>
{
    protected readonly IDictionary<DateTime, Allocation<TActivity>> _allocations;

    public virtual void ClockIn<TResource>(
        DateTime eventDate, TResource resource, TimeQuantity timeSpent) 
        where TResource : Resource
    {
        var entry = new Allocation<TActivity, TResource>(
            resource, this, eventDate, timeSpent);
        if (_allocations.ContainsKey(eventDate))
        {
            Check.Require(_allocations[eventDate].Resource.Equals(resource),
                          "This method requires that the same resource is the resource in this allocation.");
            _allocations[eventDate] = entry;
        }
        else _allocations.Add(eventDate, entry);
    }
}
public class Allocation<TActivity> 
    where TActivity : AllocatableActivity<TActivity>
{

    public AllocatableResource Resource { get; private set; }
    public TActivity Activity { get; private set; }
    public TimeQuantity Period { get; private set; }

    public Allocation(AllocatableResource resource, TActivity activity, DateTime eventDate, TimeQuantity timeSpent)
    {
        Check.RequireNotNull<IResource>(resource);
        Resource = resource;

        Check.RequireNotNull<Activities.Activity>(activity);
        Activity = activity;

        Check.Require(timeSpent.Amount >= 0, Msgs.Allocation_NegativeTimeSpent);
        TimeSpentPeriod = _toTimeSpentPeriod(eventDate, timeSpent);
    }
}

public class AllocatableActivity<TActivity>
{

    public string Description { get; protected set; }
    public string BusinessId { get; protected set; }

    protected readonly IDictionary<DateTime, Allocation<TActivity>> _allocations;

    public virtual void ClockIn(DateTime eventDate, AllocatableResource resource, TimeQuantity timeSpent)
    {
        var entry = new Allocation<TActivity>(resource, this, eventDate, timeSpent);
        if (_allocations.ContainsKey(eventDate))
        {
            Check.Require(_allocations[eventDate].Resource.Equals(resource),
                      "This method requires that the same resource is the resource in this allocation.");
            _allocations[eventDate] = entry;
        }
        else _allocations.Add(eventDate, entry);
    }
}