看作C#无法打开一个Type(我收集的并不是作为特殊情况添加的,因为is-a关系意味着可能有多个不同的情况可能适用),是否有更好的方法来模拟切换类型?
void Foo(object o)
{
if (o is A)
{
((A)o).Hop();
}
else if (o is B)
{
((B)o).Skip();
}
else
{
throw new ArgumentException("Unexpected type: " + o.GetType());
}
}
Run Code Online (Sandbox Code Playgroud) 可能重复:
C# - "开启类型"有比这更好的选择吗?
C#不支持切换对象的类型.模拟这个的最佳模式是什么:
switch (typeof(MyObj))
case Type1:
case Type2:
case Type3:
Run Code Online (Sandbox Code Playgroud)
谢谢!
我最近一直在关注F#,虽然我不太可能在不久的将来跳过障碍,但它肯定会突出一些C#(或库支持)可以让生活更轻松的领域.
特别是,我正在考虑F#的模式匹配功能,它允许非常丰富的语法 - 比当前的开关/条件C#等价物更具表现力.我不会试图给出一个直接的例子(我的F#不符合它),但简而言之它允许:
虽然C#最终可以借用[ahem]丰富的一些内容,但是在过渡时期我一直在研究可以在运行时做些什么 - 例如,将一些对象拼凑起来相当容易:
var getRentPrice = new Switch<Vehicle, int>()
.Case<Motorcycle>(bike => 100 + bike.Cylinders * 10) // "bike" here is typed as Motorcycle
.Case<Bicycle>(30) // returns a constant
.Case<Car>(car => car.EngineType == EngineType.Diesel, car => 220 + car.Doors * 20)
.Case<Car>(car => car.EngineType == EngineType.Gasoline, car => 200 + car.Doors * 20)
.ElseThrow(); // or could use a Default(...) terminator
Run Code Online (Sandbox Code Playgroud)
其中getRentPrice是Func <Vehicle,int>.
[注意 - 也许这里的Switch/Case是错误的术语......但它显示了这个想法]
对我来说,这比使用重复的if/else或者复合三元条件(对于非平凡的表达式变得非常混乱 - 括号丰富)的等价物要清楚得多.它还避免了大量的转换,并允许简单扩展(直接或通过扩展方法)到更具体的匹配,例如InRange(...)匹配可比VB选择...案例"x到y "用法.
我只是想测量一下,如果人们认为上述结构有很多好处(在没有语言支持的情况下)?
另外请注意,我一直在玩上述3种变体: …
假设我可以选择在字符串比较的基础上识别代码路径,或者如果确定类型:
哪个更快,为什么?
switch(childNode.Name)
{
case "Bob":
break;
case "Jill":
break;
case "Marko":
break;
}
if(childNode is Bob)
{
}
elseif(childNode is Jill)
{
}
else if(childNode is Marko)
{
}
Run Code Online (Sandbox Code Playgroud)
更新:我问这个问题的主要原因是因为switch语句对于什么算是一个特例.例如,它不允许您使用变量,只允许移动到主程序集的常量.我认为它有这个限制,因为它正在做一些时髦的东西.如果它只是翻译成elseifs(作为一张海报评论)那么为什么我们不允许在case语句中使用变量?
警告:我是后期优化的.这种方法被称为许多在应用程序的缓慢一部分倍.
可能重复:
"开启类型"有比这更好的选择吗?
我需要迭代我的类的所有属性,并检查我的类型int是否需要做什么,如果它的字符串..然后做一些事情.我需要使用开关盒.这里我以下面的方式使用switch,但它要求一些常量.看下面的代码:
public static bool ValidateProperties(object o)
{
if(o !=null)
{
var sourceType = o.GetType();
var properties = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Static);
foreach (var property in properties)
{
var type = property.GetType();
switch (type)
{
*case typeof(int):* getting error here
// d
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
另外我想知道,我应该使用什么检查,typeof(int)或typeof(Int32)?
可能重复:
C# - "开启类型"有比这更好的选择吗?
考虑经典:
class Widget { }
class RedWidget : Widget { }
class BlueWidget : Widget { }
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,在我的用户界面中,我可以对待所有Widget相同的内容.但是,我需要if或switch通过一些细微差别.
可能的方法:
枚举指标 - 由构造函数设置
enum WidgetVariety { Red, Blue }
class Widget {
public WidgetVariety Variety { get; protected set; }
}
class RedWidget : Widget {
public RedWidget() {
Variety = Red;
}
}
// Likewise for BlueWidget...
switch (mywidget.Variety) {
case WidgetVariety.Red:
// Red specific GUI stuff
case WidgetVariety.Blue:
// …Run Code Online (Sandbox Code Playgroud) 我有一个List<object>.我想循环遍历列表并以更友好的方式打印出值,而不仅仅是o.ToString()在某些对象是布尔值或日期时间等情况下.
你将如何构造一个我可以调用的函数MyToString(o)并返回一个正确格式化的字符串(由我指定)作为其实际类型?
可能重复:
C# - "开启类型"有比这更好的选择吗?
我的公司遗留代码有如下内容
public override Uri GetUri(object obj)
{
if ((obj is Entry) || (obj is EntryComment))
{
//
}
if (obj is Blog)
{
//
}
// if obj is blah blah blah
}
Run Code Online (Sandbox Code Playgroud)
这种方法很难看.我想重构它,但我不知道迭代obj可能的"可能"类型的技术.
我怎么能重构这个?
谢谢.