我知道这是一件非常令人困惑和奇怪的事情,但是有什么方法可以基于对象的属性来执行switch语句。就像传入对象的属性一样,不传递属性的值而是传递属性本身,并进行开关求值?
主要目标是让一个对象具有一堆不同的属性,并且每个属性都具有确定整个对象是true还是false的条件,因此我希望能够从多个位置调用单个方法,并让每个位置都说要检查其T / F的属性。
ex:
public class Foo{
public int StuffsLimit{get;set;}
public List<int> SomeList {get;set;}
}
...
switch(x){
case Foo.StuffsLimit:
//here, we check whether THIS condition is true
return numberOfStuffs < StuffsLimit;
case Foo.SomeList:
//here, we check if a different condition is true
return SomeList.Contains(5);
}
这样做是为了尽量减少多余/冗余的代码。可能需要在多个位置检查同一属性,所以我想避免将实际检查放在这些位置,但我也想避免对所有内容使用Enum或单独的方法,以便在添加新属性时可以动态工作到原始对象。
谢谢
这是一些经典的面向对象的多态性的理想情况,这是当您不知道拥有哪种类型的对象,但是知道时,您想要不同类型的对象具有不同行为的另一种方式从特定的基类继承。
public class Foo
{
public abstract bool Evaluate();
}
public class FooChildA : Foo
{
public int StuffsLimit { get; set; }
public override bool Evaluate()
{
return numberOfStuffs < StuffsLimit;
}
}
public class FooChildB : Foo
{
public List<int> SomeList { get; set; }
public override bool Evaluate()
{
return SomeList.Contains(5);;
}
}
// Somewhere later:
Foo foo = FooChildA();
// Calls FooChildA.Evaluate();
foo.Evaluate();
foo = FooChildB();
// Calls FooChildB.Evaluate();
foo.Evaluate();
看来您需要一些验证码。我将通过验证方法一个Foo
对象以及要验证的属性的名称。
public bool IsValid(Foo foo, string propertyName)
{
switch(propertyName) {
case nameof(Foo.StuffsLimit):
return numberOfStuffs < foo.StuffsLimit;
case nameof(Foo.SomeList):
return foo.SomeList.Contains(5);
default:
return false;
}
}
使用新的C#8.0开关表达式,该表达式使成员更强壮,您可以简单地做到这一点:
public bool IsValid(Foo foo, string propertyName) =>
propertyName switch {
nameof(Foo.StuffsLimit) => numberOfStuffs < foo.StuffsLimit,
nameof(Foo.SomeList) => foo.SomeList.Contains(5),
_ => false;
};
请注意,nameof(Foo.StuffsLimit)
与"StuffsLimit"
相同。第一个变体由编译器检查,并且可以进行重命名重构,第二个则不可以。