C# 如何订购2个不同的列表?

C# 如何订购2个不同的列表?,c#,C#,我有一个Step类和一个AutoStep类 class Step { int StepNumber; } class AutoStep { int StepNumber; } 它们不是从任何类继承的,也不能从任何类继承 我必须按步骤编号对它们进行排序,并根据它们的类型调用特定的方法(Step或AutoStep) 我该怎么做呢?您可以使用as来播放它们: Step stepObject = input as Step; if(stepObject != null) { /

我有一个
Step
类和一个
AutoStep

class Step {
    int StepNumber;
}

class AutoStep {
    int StepNumber;
}
它们不是从任何类继承的,也不能从任何类继承

我必须按步骤编号对它们进行排序,并根据它们的类型调用特定的方法(
Step
AutoStep


我该怎么做呢?

您可以使用
as
来播放它们:

Step stepObject = input as Step;

if(stepObject != null)
{
  // do something with Step
}

AutoStep autoStepObject = input as AutoStep;

if(autoStepObject != null)
{
  // do something with AutoStep
}

您可以使用
as
来强制转换它们:

Step stepObject = input as Step;

if(stepObject != null)
{
  // do something with Step
}

AutoStep autoStepObject = input as AutoStep;

if(autoStepObject != null)
{
  // do something with AutoStep
}

这就是接口的真正用途:

public interface ISteppable
{
    public int StepNumber { get; }
    public void Foo();//the method you need to call; adjust the signature as needed
}

class step : ISteppable
{
    int StepNumber;

    int ISteppable.StepNumber
    {
        get { return StepNumber; }
    }

    public void Foo()
    {

    }
}

class AutoStep
{
    int StepNumber;

    int ISteppable.StepNumber
    {
        get { return StepNumber; }
    }

    public void Foo()
    {

    }
}
然后,您可以创建
istepable
对象的集合,并使用它们的
StepNumber
属性对它们进行排序,然后对每个对象调用
Foo

由于您不能修改任何一个类,因此需要使用适配器模式为这些类型创建这些接口的实现:

public class StepAdapter : ISteppable
{
    private step value;
    public StepAdapter(step value)
    {
        this.value = value;
    }

    public int StepNumber
    {
        get { return value.StepNumber; }
    }

    public void Foo()
    {
        value.Foo();
    }
}

public class AutoStepAdapter : ISteppable
{
    private AutoStep value;
    public AutoStepAdapter(AutoStep value)
    {
        this.value = value;
    }

    public int StepNumber
    {
        get { return value.StepNumber; }
    }

    public void Foo()
    {
        value.Foo();
    }
}
然后,您可以创建一个
istepable
对象的集合,当您想要添加
step
对象时,只需将其包装在
StepAdapter
中,并将所有
AutoStepAdapter
对象包装在
AutoStepAdapter
对象中

List<ISteppable> list = new List<ISteppable>();

list.Add(new StepAdapter(new step(){StepNumber = 5}));
list.Add(new AutoStepAdapter(new AutoStep(){StepNumber = 3}));

list.Sort((a, b) => a.StepNumber.CompareTo(b.StepNumber));

foreach (var item in list)
{
    item.Foo();
}
List List=新列表();
Add(newstepAdapter(newstep(){StepNumber=5}));
Add(newautostepadapter(newautostep(){StepNumber=3}));
list.Sort((a,b)=>a.StepNumber.CompareTo(b.StepNumber));
foreach(列表中的变量项)
{
item.Foo();
}

这就是界面的真正用途:

public interface ISteppable
{
    public int StepNumber { get; }
    public void Foo();//the method you need to call; adjust the signature as needed
}

class step : ISteppable
{
    int StepNumber;

    int ISteppable.StepNumber
    {
        get { return StepNumber; }
    }

    public void Foo()
    {

    }
}

class AutoStep
{
    int StepNumber;

    int ISteppable.StepNumber
    {
        get { return StepNumber; }
    }

    public void Foo()
    {

    }
}
然后,您可以创建
istepable
对象的集合,并使用它们的
StepNumber
属性对它们进行排序,然后对每个对象调用
Foo

由于您不能修改任何一个类,因此需要使用适配器模式为这些类型创建这些接口的实现:

public class StepAdapter : ISteppable
{
    private step value;
    public StepAdapter(step value)
    {
        this.value = value;
    }

    public int StepNumber
    {
        get { return value.StepNumber; }
    }

    public void Foo()
    {
        value.Foo();
    }
}

public class AutoStepAdapter : ISteppable
{
    private AutoStep value;
    public AutoStepAdapter(AutoStep value)
    {
        this.value = value;
    }

    public int StepNumber
    {
        get { return value.StepNumber; }
    }

    public void Foo()
    {
        value.Foo();
    }
}
然后,您可以创建一个
istepable
对象的集合,当您想要添加
step
对象时,只需将其包装在
StepAdapter
中,并将所有
AutoStepAdapter
对象包装在
AutoStepAdapter
对象中

List<ISteppable> list = new List<ISteppable>();

list.Add(new StepAdapter(new step(){StepNumber = 5}));
list.Add(new AutoStepAdapter(new AutoStep(){StepNumber = 3}));

list.Sort((a, b) => a.StepNumber.CompareTo(b.StepNumber));

foreach (var item in list)
{
    item.Foo();
}
List List=新列表();
Add(newstepAdapter(newstep(){StepNumber=5}));
Add(newautostepadapter(newautostep(){StepNumber=3}));
list.Sort((a,b)=>a.StepNumber.CompareTo(b.StepNumber));
foreach(列表中的变量项)
{
item.Foo();
}

如果您可以使用接口,那么问题很容易解决:

class step : IStep
{
   ...
   public int StepNumber {get; set;}
}

class AutoStep : IStep
{
   ...
   public int StepNumber {get; set;}
}

interface IStep
{
   public int StepNumber;
}

List<IStep> steps; // list with steps and autosteps
List<IStep> orderedSteps = steps.OrderBy(s => s.StepNumber);
foreach (IStep step in orderedSteps)
{
  if (step is Step)
    // call to method here
  else if (step is AutoStep)
    // call to other method here
}
类步骤:IStep
{
...
公共整数步数{get;set;}
}
类AutoStep:IStep
{
...
公共整数步数{get;set;}
}
接口IStep
{
公共国际号码;
}
列出步骤;//列出步骤和自动步骤
列出orderedSteps=steps.OrderBy(s=>s.StepNumber);
foreach(orderedSteps中的IStep步骤)
{
如果(步骤是步骤)
//在此调用方法
else if(步骤为自动步骤)
//在这里调用其他方法
}

或者,您也可以使用反射(由于性能影响,不建议这样做)。

如果您可以使用接口,那么问题很容易解决:

class step : IStep
{
   ...
   public int StepNumber {get; set;}
}

class AutoStep : IStep
{
   ...
   public int StepNumber {get; set;}
}

interface IStep
{
   public int StepNumber;
}

List<IStep> steps; // list with steps and autosteps
List<IStep> orderedSteps = steps.OrderBy(s => s.StepNumber);
foreach (IStep step in orderedSteps)
{
  if (step is Step)
    // call to method here
  else if (step is AutoStep)
    // call to other method here
}
类步骤:IStep
{
...
公共整数步数{get;set;}
}
类AutoStep:IStep
{
...
公共整数步数{get;set;}
}
接口IStep
{
公共国际号码;
}
列出步骤;//列出步骤和自动步骤
列出orderedSteps=steps.OrderBy(s=>s.StepNumber);
foreach(orderedSteps中的IStep步骤)
{
如果(步骤是步骤)
//在此调用方法
else if(步骤为自动步骤)
//在这里调用其他方法
}

或者,您也可以对反射进行处理(由于性能影响,不建议这样做)。

如果您有两种类型希望以相同的方式处理,您应该以某种方式为它们创建一种类型

在这种情况下,最好的选择是一个公共接口(或者可能是一个公共基类),但这似乎不是您的选择

另一种方法是创建接口和从中继承的两个适配器(每个原始类型一个)

这两种选择在本文中都有很好的解释

但另一种选择是使用
动态
。因此,拥有一个同名的属性就足以以相同的方式使用它们。但我不推荐这种方法,因为它破坏了(编译时)类型安全性

例如(使用Servy答案中的修改代码):

List List=新列表();
添加(新步骤{StepNumber=5});
添加(新的自动步{StepNumber=3});
foreach(list.OrderBy(x=>x.StepNumber)中的变量项)
{
item.Foo();
}

如果有两种类型需要以相同的方式处理,则应该以某种方式为它们创建一种类型

在这种情况下,最好的选择是一个公共接口(或者可能是一个公共基类),但这似乎不是您的选择

另一种方法是创建接口和从中继承的两个适配器(每个原始类型一个)

这两种选择在本文中都有很好的解释

但另一种选择是使用
动态
。因此,拥有一个同名的属性就足以以相同的方式使用它们。但我不推荐这种方法,因为它破坏了(编译时)类型安全性

例如(使用Servy答案中的修改代码):

List List=新列表();
添加(新步骤{StepNumber=5});
添加(新的自动步{StepNumber=3});
foreach(list.OrderBy(x=>x.StepNumber)中的变量项)
{
item.Foo();
}

这肯定不是我在不受严格约束的情况下做事情的方式,但您可以使用以下排序方法:

private void sort(object toBeSorted)
{
    if(toBeSorted is Step)
    {
        callStepSort();
    }
    else if(toBeSorted is AutoStep)
    {
        callAutoStepSort();
    }
}
这将负责检查类型,避免继承,并允许您调用sort方法,而不考虑类型


但同样,没有约束,这根本不是我完成这项工作的方式。

这绝对不是我在不受严格约束的情况下如何做事的方式,但您可以使用以下排序方法:

private void sort(object toBeSorted)
{
    if(toBeSorted is Step)
    {
        callStepSort();
    }
    else if(toBeSorted is AutoStep)
    {
        callAutoStepSort();
    }
}
这将负责检查类型,避免继承,并允许您调用sort方法,而不考虑类型

但是,w
autoStepList.Sort(AnyStepComparer<AutoStep>.Default);
stepList.Sort(AnyStepComparer<Step>.Default);