使用案例/开关和的GetType以确定物体[重复]
-
22-08-2019 - |
题
<强>可能重复:强>结果 C# - 有没有更好的替代比这为“上型开关”?
如果您想switch
一个类型的对象,什么是做到这一点的最好方法是什么?
代码段
private int GetNodeType(NodeDTO node)
{
switch (node.GetType())
{
case typeof(CasusNodeDTO):
return 1;
case typeof(BucketNodeDTO):
return 3;
case typeof(BranchNodeDTO):
return 0;
case typeof(LeafNodeDTO):
return 2;
default:
return -1;
}
}
我知道这不工作的方式,但我不知道你怎么能解决这个问题。
是if/else
声明适当在这种情况下?
或者你使用的开关,并添加.ToString()
的类型?
解决方案
如果我的真正的不得不switch
对类型的对象,我会使用.ToString()
。不过,我会避免不惜一切代价:IDictionary<Type, int>
会做的更好,游客可能是矫枉过正但否则它仍然是一个完全没有问题的解决方案。
其他提示
只要你想在自己的用户定义类型转换这不会直接解决您的问题,但对于其他人的利益谁只想打开内置类型,可以使用的类型码枚举:
switch (Type.GetTypeCode(node.GetType()))
{
case TypeCode.Decimal:
// Handle Decimal
break;
case TypeCode.Int32:
// Handle Int32
break;
...
}
在MSDN博客文章的 许多问题:开关上型 是为什么 .NET 不提供某些信息接通的类型。
像往常一样 - 解决方法总是存在
这一个不是我的,但不幸的是我已经失去了所述源。这使得对各类可能的开关,但我个人认为这是相当尴尬(字典的想法是更好):
public class Switch
{
public Switch(Object o)
{
Object = o;
}
public Object Object { get; private set; }
}
/// <summary>
/// Extensions, because otherwise casing fails on Switch==null
/// </summary>
public static class SwitchExtensions
{
public static Switch Case<T>(this Switch s, Action<T> a)
where T : class
{
return Case(s, o => true, a, false);
}
public static Switch Case<T>(this Switch s, Action<T> a,
bool fallThrough) where T : class
{
return Case(s, o => true, a, fallThrough);
}
public static Switch Case<T>(this Switch s,
Func<T, bool> c, Action<T> a) where T : class
{
return Case(s, c, a, false);
}
public static Switch Case<T>(this Switch s,
Func<T, bool> c, Action<T> a, bool fallThrough) where T : class
{
if (s == null)
{
return null;
}
T t = s.Object as T;
if (t != null)
{
if (c(t))
{
a(t);
return fallThrough ? s : null;
}
}
return s;
}
}
用法:
new Switch(foo)
.Case<Fizz>
(action => { doingSomething = FirstMethodCall(); })
.Case<Buzz>
(action => { return false; })
我只是使用if语句。在这种情况下:
Type nodeType = node.GetType();
if (nodeType == typeof(CasusNodeDTO))
{
}
else ...
在其他的方法来做到这是:
if (node is CasusNodeDTO)
{
}
else ...
在第一个例子是真对确切类型只,其中对于继承后者检查过。
我面临着同样的问题,碰到这个岗位来了。 这是什么年代由IDictionary的方法意味着:
Dictionary<Type, int> typeDict = new Dictionary<Type, int>
{
{typeof(int),0},
{typeof(string),1},
{typeof(MyClass),2}
};
void Foo(object o)
{
switch (typeDict[o.GetType()])
{
case 0:
Print("I'm a number.");
break;
case 1:
Print("I'm a text.");
break;
case 2:
Print("I'm classy.");
break;
default:
break;
}
}
如果是这样,我不能说我在与case语句字典调和数的粉丝。
这将是理想的,但字典参考杀死它:
void FantasyFoo(object o)
{
switch (typeDict[o.GetType()])
{
case typeDict[typeof(int)]:
Print("I'm a number.");
break;
case typeDict[typeof(string)]:
Print("I'm a text.");
break;
case typeDict[typeof(MyClass)]:
Print("I'm classy.");
break;
default:
break;
}
}
是否有我忽视了另一种实现方式?
您可以这样做:
if (node is CasusNodeDTO)
{
...
}
else if (node is BucketNodeDTO)
{
...
}
...
虽然这将是更优雅,它可能不一样有效,这里的一些其他的答案。
您可以这样做:
function void PrintType(Type t) {
var t = true;
new Dictionary<Type, Action>{
{typeof(bool), () => Console.WriteLine("bool")},
{typeof(int), () => Console.WriteLine("int")}
}[t.GetType()]();
}
很显然和它的方便。 它不是某个缓存字典有点慢..但对于大量的代码,这将不会怎样都无所谓..
一种方法是一个纯虚拟GetNodeType()方法添加到NodeDTO和使得每个后代返回实际类型覆盖它在后代。
根据您的switch语句在做什么,正确答案是多态性。只要把一个虚拟函数的接口/基类并覆盖每个节点类型。
其实我更喜欢给出如下答案的方法: 有没有更好的替代比此为 '开关型'?
有然而是关于如C#面向对象的语言不执行任何类型的比较methids良好的论点。你可以作为替代延伸,并且使用继承添加额外的所需的功能。
这点是在作者的博客中的评论讨论: 的http://博客。 msdn.com/b/jaredpar/archive/2008/05/16/switching-on-types.aspx#8553535
我发现这一个非常有趣的点,这改变了我的做法,类似的情况,只是希望这可以帮助别人。
此致韦恩