继承问题,C# [英] Issues with inheritance, C#

查看:78
本文介绍了继承问题,C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有基本抽象类功能,如下所示:

Suppose, I have the base abstract class Function that looks like this:

public abstract class Function
{
   public abstract string Invoke(string[] args);
}



我还有一个子类 DeterministicFunction ,如下所示:


And also I have a child sub-class DeterministicFunction that looks like this:

public abstract class DeterministicFunction : Function
{
    private readonly Dictionary<string[], string> _cache;

    public sealed override string Invoke(string[] args)
    {
         if (args?.Length > 0)
         {
             string fnResult;
             if (_cache.TryGetValue(args, out fnResult))
                 return fnResult;

             fnResult = GetResult(args);
             _cache[args] = fnResult;
             return fnResult;
         }

         return GetResult(args);
    }

    protected abstract string GetResult(string[] args);
}



所有功能可以是**确定性**或**非确定性**。

确定性函数总是为相同的参数组合返回相同的结果,因此我决定通过将结果放入缓存来优化它,因此如果使用已调用的参数调用昂贵的函数,它可以缓存结果并更快地检索它。我还有一堆与日期和时间相关的非确定性函数。时间。它们是非确定性的,因为它们会在每次调用时返回
不同的结果。我的日期和基础班级时间函数:


All functions can be either **deterministic** or **non-deterministic**.
Deterministic function always returns same result for same combination of arguments, so I decided to optimize it by putting result to cache so if expensive function is invoked with already invoked arguments it could cache result and retrieve it faster. I also have a bunch of non-deterministic functions related to date & time. They are non-deterministic cause they return
different result with every invocation. My base class for date & time functions:

public abstract class DateTimeFunction : Function
{
     private CultureInfo _culture;

     protected DateTimeFunction(CultureInfo culture)
     {
         _culture = culture;
     }

     protected CultureInfo Culture => _culture;
}

public class UtcNowFunction : DateTimeFunction
{
     // skip constructor code, too long to type

     public override string Invoke(string[] args)
     {
         DateTime now = DateTime.NowUtc;
         string result = now.ToString(Culture);

         if (args?.Length > 0)
         {
            string format = args[0];
            result = now.ToString(format, Culture);
         }

         return result;
     }
}



我的问题是 - 我是否需要为所有非确定性函数创建基类?目前,我没有看到添加新抽象级别的理由,但将它们分成两个主要组是合乎逻辑的。如果我创建一个新的抽象类 NonDeterministicFunction - 它将是空的。我该怎么办?



我的尝试:



我没有创建一个子类 NonDeterministicFunction 因为我现在,只是现在我认为没有理由这样做。但我确实关心逻辑设计,将抽象实体分离到不同的组是合乎逻辑的


My question is - do I need to create a base class for all non-deterministic functions? For now, I don't see reasons to add a new abstract level, but it would be logical to separate them into two major groups. If I create a new abstract class NonDeterministicFunction - it's going to be empty. What should I do??

What I have tried:

I did not create a sub-class NonDeterministicFunction cause I for now, only for now I see no reasons to do it. But I do care about logical design, and it would be logical to separate abstract entity to different groups

推荐答案

我为NonDeterministicFunction创建共享基类的唯一原因是如果存在可以/可以在这些非确定性函数的所有实现中共享的逻辑。



您仍然可以使用抽象类作为基类作为选项好吧。



就个人而言,我已经将它作为一个接口(调用方法)实现并使用抽象类作为基类(如果需要)仅在从其继承的所有类中托管公共方法。



如果使用函数的抽象类作为NonDeterministic和Deterministic函数的基础,那么您将公开仅涉及这些函数的一方的实现(例如:确定性的)如果对两种类型的确定性函数使用抽象Function类,则类将能够查看/实现非确定性方法(可能)。



所以我会将NonDeterministic特定实现放入INonDeterministicFunctions接口,其余的放在IDeterministicFunctions中。然后任何共享逻辑都将进入Function基类。然后任何特定于NonDeterministicFunctions的共享逻辑都可以进入NonDeterministic基类。



如果我理解你的话,这就像我将重构的那样



The only reason I would create a shared base class for NonDeterministicFunction is if there is logic that would/could be shared across all implementations of these non deterministic functions.

You can still use your abstract class as the base class as an option as well.

Personally, what you've got I would have implemented it as an interface (the invoke method) and use an abstract class to serve as the base class (if needed) to only host the common methods across all classes that inherit from it.

If you use your abstract class of Function to serve as base for both NonDeterministic and Deterministic functions you are exposing implementation that only concerns one side of those functions (Ex: deterministic classes would be able to see/implement nondeterministic methods (potentially) if you use the abstract Function class for both types of deterministic functions).

So i would put the NonDeterministic specific implementation into INonDeterministicFunctions interface and the rest in IDeterministicFunctions. Then any shared logic would go into the Function base class. Then any shared logic specific to NonDeterministicFunctions could go into a NonDeterministic base class.

If i understood you right, this is something like what i would refactor to

public IFunction
{
    string Invoke(string[] args)
}

public abstract class BaseFunction
{
    // common logic shared across function types here
}

public abstract class NonDeterministicFunction : BaseFunction
{
   // common non-deterministic specific functionality here
}

public abstract class DeterministicFunction : BaseFunction
{
   // common deterministic specific functionality here
}


public abstract class DateTimeFunction : DeterministicFunction
{
     private CultureInfo _culture;

     protected DateTimeFunction(CultureInfo culture)
     {
         _culture = culture;
     }

     protected CultureInfo Culture => _culture;
}

public class UtcNowFunction : DateTimeFunction, IFunction
{
     // skip constructor code, too long to type

     public string Invoke(string[] args)
     {
         DateTime now = DateTime.NowUtc;
         string result = now.ToString(Culture);

         if (args?.Length > 0)
         {
            string format = args[0];
            result = now.ToString(format, Culture);
         }

         return result;
     }
}





接口的原因是它描述了类应该是什么的实现无论从哪里继承。鉴于实现是特定于类,对我来说它似乎最好作为一个接口。



你可能会发现不需要NonDeterministic / Deterministic类而你可以使用1个BaseFunction类,并具有确定性非确定性特定实现的接口。



但是我确定你知道有10种不同的方法来做所有事情所以我的建议可能不是100%你想要的,也可能是过度设计的。



The reason for the interface is that it describes the implementation of what the class should be for whatever inherits from it. Given the implementation is specific to the class, to me it seems best served as an interface.

You may find that the NonDeterministic/Deterministic classes aren't needed and you can just make do with 1 BaseFunction class and have interfaces for the deterministic nondeterministic specific implementations.

But as im sure you know there are 10 different ways to do everything so my suggestion may not be 100% what you want and possibly over engineered.


这篇关于继承问题,C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆