【问题标题】:C# Override when there are specific methods involved in a variable / object当变量/对象中涉及特定方法时,C# Override
【发布时间】:2020-06-05 23:37:00
【问题描述】:

我知道如何创建虚拟方法并覆盖它们。示例

基类:

var service = GetConnectionKeyString();

protected virtual string GetConnectionKeyString()
{
    return "wpshook";
}

子类:

protected override string GetConnectionKeyString()
{
   return "newthing";
} 

但是,我想更改一条消息,其中包含 JObject 以及方法调用和其他对象

目前在抽象基类方法中是这段代码

var message = JObject.FromObject(new
        {
            Component = GetComponentName(),
            WorkflowName = workspaceContext.WorkItem.Workflow.TransactionName,
            RecordType = GetRecordType(configuration, workspaceContext),
            RecordId = GetRecordId(configuration, workspaceContext),
            RecordStatus = GetRecordStatus(configuration, workspaceContext),
            ICN = GetICN(configuration, workspaceContext),

        });

所以我正在添加一个虚拟方法来覆盖此消息

 protected virtual string OverRideNotificationMessage()
 {
    return "";   //open/close principle  -  don't effect the other subclasses
 }

所以在我的子类中,使用覆盖 - 我如何能够替换“var message”中近一半的代码?

例子

    //replace  
    ICN = GetICN(configuration, workspaceContext) 
    //with 
    FileName = .....  

根据 cmets...

var message = JObject.FromObject(new
        {
            Component = GetComponentName(),
            WorkflowName = workspaceContext.WorkItem.Workflow.TransactionName,
            RecordType = GetRecordType(configuration, workspaceContext),
            RecordId = GetRecordId(configuration, workspaceContext),
            RecordStatus = GetRecordStatus(configuration, workspaceContext),
            //per comment replace  ICN with FileName, and possibly replace other lines
            FileName = GetFileName(configuration, workspaceContext),

        });

更新具体例子:

基类:

 public abstract class BaseStatusNotification<TContext> : IWorkflowRule<TContext> where TContext : IWorkflowContext
{
    public StepResult Process(IWorkflowClient workflowClient, ITransactionStep configuration, TContext workspaceContext)
    {

        var message = JObject.FromObject(new
        {
            Component = GetComponentName(),
            WorkflowName = workspaceContext.WorkItem.Workflow.TransactionName,
            RecordType = GetRecordType(configuration, workspaceContext),
            RecordId = GetRecordId(configuration, workspaceContext),
            RecordStatus = GetRecordStatus(configuration, workspaceContext),
            ICN = GetICN(configuration, workspaceContext),

        });

        // this most likely should not be here, but only in a subclass
        // wondering if I should have if statement is override is not null?
        OverRideNotificationMessage(configuration, workspaceContext, message);

        var serviceBusClient = QueueManagerFactory.GetQueueSender(workspaceContext.InstanceId,
                                                                    workspaceContext.WorkItem.Workflow.Component,
                                                                    GetConnectionKeyString(), null);

        if (serviceBusClient == null)
        {
            return StepResult.Error;
        }

        serviceBusClient.Enqueue(TimeSpan.Zero, message);

        return StepResult.Success;

    }
    protected virtual string GetConnectionKeyString()
    {
        return "wpshook";
    }

    protected virtual string OverRideNotificationMessage(ITransactionStep configuration, TContext workspaceContext, JObject message)
    {
        return "";
    }

然后是一个典型的子类:

public class SendClaimStatusNotification : BaseStatusNotification<IBizClaimWorkflowContext>
{

    protected override string GetICN(ITransactionStep configuration, IBizClaimWorkflowContext workspaceContext)
    {
        var claimHeader = workspaceContext.GetClaimHeader();
        return claimHeader.AdditionalClaimId;
    }

    protected override string GetRecordStatus(ITransactionStep configuration, IBizClaimWorkflowContext workspaceContext)
    {
        var claimHeader = workspaceContext.GetClaimHeader();
        return claimHeader.StatusCode;
    }

    protected override string GetRecordId(ITransactionStep configuration, IBizClaimWorkflowContext workspaceContext)
    {
        var claimHeader = workspaceContext.GetClaimHeader();
        return claimHeader.ClaimId;

    }

    protected override string GetRecordType(ITransactionStep configuration, IBizClaimWorkflowContext workspaceContext)
    {
        return "Claim";
    }

    protected override string GetComponentName()
    {
        return FrameworkConstants.Components.VidaClaim;           
    }
    protected override string GetConnectionKeyString()
    {
        return "wpshook";
    }
}

现在,我想要一个覆盖来换出 var 消息....

我不清楚如何替换生成 json 的 JObject 中的几个匿名类型和方法。我正在玩一个新的子类并创建它

protected override string OverRideNotificationMessage(ITransactionStep configuration, ITEDTransactionWorkflowContext workspaceContext, JObject message)
    {
        var messageq = JObject.FromObject(new
        {
            Component = GetComponentName(),
            WorkflowName = workspaceContext.WorkItem.Workflow.TransactionName,
            RecordType = GetRecordType(configuration, workspaceContext),
            RecordId = GetRecordId(configuration, workspaceContext),
            RecordStatus = GetRecordStatus(configuration, workspaceContext),
            //ICN = GetICN(configuration, workspaceContext),
            FileName = "something else"

        });

        return base.OverRideNotificationMessage(configuration, workspaceContext, message);
    }

【问题讨论】:

  • 您的最后一个问题与其余的解释完全脱节。你想达到什么目的?
  • @trailmax 抱歉 - ICN = GetICN 在 var 消息内......例如,我想用 FileName 替换 ICN 的 json 结构......以及其他字段。我只是迷失了如何替换 var 消息 - JObject 等......通过覆盖
  • 真的不确定您在这里要问什么,所以这是一个最好的猜测 - 您是否考虑过从您用自定义逻辑覆盖的另一种方法返回 message?你不能为了改变状态而在函数中途中断代码流 - 不能没有来自在派生类型上实现的虚拟或抽象方法的状态。
  • @ColinM - 您是否考虑过查看粘贴的基类和子类并提供答案而不是添加到 cmets?
  • 不知何故,我认为您应该将消息的发送和不同类的格式分开。也许创建一个 IMessageFormatter 接口和不同的实现,它们会生成不同的 JSON 消息。 MessageSender 可以使用 IMessageFormatter...

标签: c# oop abstract-base-class


【解决方案1】:

如果我正确理解了您的要求,那么您正在寻找的是更改生成的 json 对象的结构,具体取决于创建 json 消息的子类。

这有帮助吗?

// this is defined in a superclass
public virtual JObject NewMessage() {
   var message = JObject.FromObject(new
        {
            Component = GetComponentName(),
            WorkflowName = workspaceContext.WorkItem.Workflow.TransactionName,
            RecordType = GetRecordType(configuration, workspaceContext),
            RecordId = GetRecordId(configuration, workspaceContext),
            RecordStatus = GetRecordStatus(configuration, workspaceContext),
            ICN = GetICN(configuration, workspaceContext),

        });
   return message;
}

public StepResult Process(IWorkflowClient workflowClient, ITransactionStep configuration, TContext workspaceContext)
{
    // instead of hardcoding the message structure, call an overridable function
    // so we may provide a different message structure if needed
    var message = NewMessage();
    ...
}

然后子类可以覆盖 NewMesage() 并提供不同的结构

public override JObject NewMessage() {
   var message = JObject.FromObject(new
     {
            Component = GetComponentName(),
            WorkflowName = workspaceContext.WorkItem.Workflow.TransactionName,
            RecordType = GetRecordType(configuration, workspaceContext),
            RecordId = GetRecordId(configuration, workspaceContext),
            RecordStatus = GetRecordStatus(configuration, workspaceContext),
            FileName = "something else"  // FileName instead of ICN

     });
   return message;
}

在这里您有很大的灵活性,因为如果您想定制特定成员如何获取其值,您可以覆盖任何 Get... 方法,或者您可以覆盖 NewMessage() 方法并提供完全不同的消息如果这是要求的结构

【讨论】:

    猜你喜欢
    • 2021-08-05
    • 2019-04-12
    • 1970-01-01
    • 2013-11-01
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    相关资源
    最近更新 更多