将对象转换为指定的类最佳实践

Sim*_*der 1 c# casting

我有一个方法可以获得object各种类型的方法.根据的type了的object,我需要做不同的动作.我目前的代码是这样的:

public void SomeMethod(object obj)
{
    int? someId = null;

    Class1 class1 = obj as Class1;
    Class2 class2 = obj as Class2;
    Class3 class3 = obj as Class3;
    Class4 class4 = obj as Class4;

    if (class1 != null && class1.SomeProperty != null)
    {
        someId = class1.SomeProperty.Id;
    }
    else if (class2 != null && class2.AnotherProperty != null)
    {
        someId = class2.AnotherProperty.AnotherId;
    }
    ...

    AnotherMethod(someId);
}
Run Code Online (Sandbox Code Playgroud)

我对这段代码不太满意,因为我有一些不必要的演员.哪种操作最有效?我在考虑这样的事情:

if (obj.GetType().Equals(typeOf(Class1))
{
    someId = ((Class1)obj).SomeProperty.Id;
}
Run Code Online (Sandbox Code Playgroud)

有什么建议?

das*_*ght 5

两种选择都非常糟糕,因为它们进行显式转换,并通过手动检查类型进行分派.这很容易出错,当您展开方法需要处理的类型列表时,会导致不可避免的维护问题.

从.NET 4.0开始,您有一个更好的选择 - 使用dynamic以下方式调度:

public void SomeMethod(dynamic obj) {
    SomeMethodImpl(obj);
}
private void SomeMethodImpl(Class1 obj) {
    // Perform actions specific to Class 1
}
private void SomeMethodImpl(Class2 obj) {
    // Perform actions specific to Class 2
}
private void SomeMethodImpl(Class3 obj) {
    // Perform actions specific to Class 3
}
private void SomeMethodImpl(Class4 obj) {
    // Perform actions specific to Class 4
}
private void SomeMethodImpl(object obj) {
    // Catch all
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以将特定于类的代码放在其自己的重载中SomeMethodImpl,而无需运行条件语句链.扩展处理其他类型的方法也很简单 - 您只需添加另一个重载即可.

注意:我认为签名SomeMethod必须保持不变 - 换句话说,你不能简单地通过重载 来解决这个问题SomeMethod.