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);