加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 双发和备用

发布时间:2020-12-15 06:49:37 所属栏目:百科 来源:网络整理
导读:我试图找到一个更好的方法来处理一些不断增长的if构造来处理不同类型的类.这些类最终是围绕不同的值类型(int,DateTime等)包装一些额外的状态信息.所以这些类之间的主要区别是它们包含的数据类型.虽然它们实现通用接口,但它们也需要保存在同构的集合中,因此它
我试图找到一个更好的方法来处理一些不断增长的if构造来处理不同类型的类.这些类最终是围绕不同的值类型(int,DateTime等)包装一些额外的状态信息.所以这些类之间的主要区别是它们包含的数据类型.虽然它们实现通用接口,但它们也需要保存在同构的集合中,因此它们还实现了非通用接口.类实例根据它们所代表的数据的类型来处理,并且它们的传播继续或不会继续.

虽然这不一定是.NET或C#问题,我的代码在C#中.

示例类:

interface ITimedValue {
 TimeSpan TimeStamp { get; }
}

interface ITimedValue<T> : ITimedValue {
 T Value { get; }
}

class NumericValue : ITimedValue<float> {
 public TimeSpan TimeStamp { get; private set; }
 public float Value { get; private set; }
}

class DateTimeValue : ITimedValue<DateTime> {
 public TimeSpan TimeStamp { get; private set; }
 public DateTime Value { get; private set; }
}

class NumericEvaluator {
 public void Evaluate(IEnumerable<ITimedValue> values) ...
}

我想出了两个选择:

双发

我最近才了解到访客模式及其使用双重调度来处理这种情况.这种呼吁是因为它会允许不需要的数据不能传播(如果我们只想处理一个int,我们可以处理与DateTime的不同).此外,处理不同类型的行为将仅限于处理调度的单个类.但是,如果/当需要支持新的值类型时,会有一些维护.

联盟班

包含每个支持的值类型的属性的类可以是这些类存储的每个类型.对值的任何操作将影响适当的组件.这不仅仅是双重调度策略的复杂性和维护性,而是意味着每一块数据都会不必要地传播,因为你不能再根据这种数据类型进行区分”.然而,如果/当需要支持新类型时,它们只需要进入这个类(加上需要创建以支持新数据类型的其他类).

class UnionData {
 public int NumericValue;
 public DateTime DateTimeValue;
}

有更好的选择吗?在这两个选项中有一些我不认为我应该的东西吗?

解决方法

方法1,使用动态双重发送(信用到 http://blogs.msdn.com/b/curth/archive/2008/11/15/c-dynamic-and-multiple-dispatch.aspx).
基本上你可以让你的访客模式简化如下:
class Evaluator {
 public void Evaluate(IEnumerable<ITimedValue> values) {
    foreach(var v in values)
    {
        Eval((dynamic)(v));
    }
 }

 private void Eval(DateTimeValue d) {
    Console.WriteLine(d.Value.ToString() + " is a datetime");
 }

 private void Eval(NumericValue f) {
    Console.WriteLine(f.Value.ToString() + " is a float");
 }

}

使用样本:

var l = new List<ITimedValue>(){
    new NumericValue(){Value= 5.1F},new DateTimeValue() {Value= DateTime.Now}};

new Evaluator()
    .Evaluate(l);
       // output:
       // 5,1 is a float
       // 29/02/2012 19:15:16 is a datetime

方法2将使用@Juliet here(替代实现here)提出的c#中的联盟类型,

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读