如何在C#中链接方法时强制转换

时间:2015-08-24 14:13:15

标签: c# syntax casting

我试图编写一些东西,而且我总是返回对象本身,所以我可以继续链接。喜欢这个

object.SetThis().SetThat().SetThisThirdThing().setThisFourthThing();

我在所有方法中都会返回这个,所以我可以继续这样做。但是我的一个方法是我在基类中创建的,当然然后返回基类。

所以它不是public MyClass SetThat()而是返回public SuperClass SetThat()。因为它返回SuperClass而不是MyClass,所以我无法调用SetThisThirdThing(),因为基类并不知道它。

那么我如何施展它以便保持链条?语法是什么?我试过了

object.SetThis().(MyClass)SetThat().SetThisThirdThing().setThisFourthThing();

或者有没有办法让superClass方法在从子类调用时返回子类而不必在所有子类中重写它?

这是所有子类共有的东西之一,所以如果我能够以某种方式绕过它而不必在所有子类中覆盖它,那将是非常好的。

7 个答案:

答案 0 :(得分:5)

  

有没有办法让superClass方法在从子类调用时返回子类,而不必在所有子类中重写它?

你能让超类通用吗?

public class SuperClass<T> where T: SuperClass<T>
{
    public T SetThis()
    {
        ....
        return (T)this;
    }
}

public class SubClass : SuperClass<SubClass>
{
}

请注意,由于您也可以这样做,因此不能100%保证:

public class EvilSubClass : SuperClass<SubClass>
{
}

符合通用约束,但现在SetThis()的返回类型为SubClass而非EvilSubClass

答案 1 :(得分:1)

var obj = ((MyType)myObject.SetThis()).SetThat();

P.S你应该避免这样做,因为阅读会让你感到很困惑。

答案 2 :(得分:1)

试试这样:

((MyClass)object.SetThis().SetThat()).SetThisThirdThing()

答案 3 :(得分:1)

要转换(子)表达式,您需要将类名放在前面(并使用括号)。

((MyClass)obj.SetThis().SetThat()).SetThisThirdThing().setThisFourthThing();

(请注意object是保留字,因此您无法将其用作变量名称)

另一种方法是使用as关键字:

(obj.SetThis().setThat() as MyClass).SetThisThirdThing().setThisFourthThing();

请注意,如果setThat()没有返回MyClass,则行为会有所不同。 第一个版本会抛出InvalidCastException,第二个版本会抛出NullReferenceException,因为如果无法投放,as会返回null

答案 4 :(得分:0)

只需使用括号:

(MyClass)(object.SetThis().SetThat()).SetThisThirdThing().setThisFourthThing();

我不知道为什么object存在,但你可以安全地删除它。

(MyClass)(SetThis().SetThat()).SetThisThirdThing().setThisFourthThing();

答案 5 :(得分:0)

如果不修改类,您也可以像这样编写扩展方法public static T As<T>(this MyBaseClass obj) where T : MyBaseClass { return (T)obj; }

new MyChildClass().SetBase().As<MyChildClass>().SetThis();

-

用法与此类似

let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.tap()
passwordSecureTextField.typeText("wrong_password") //here is an error

答案 6 :(得分:0)

为什么不这样做呢?一个简单的Cast方法可以帮助您将其强制转换为正确的类型...

class Program
{
    static void Main(string[] args)
    {
        var obj = new MyClass();
        //obj.SetThis().SetThat().SetThisThirdThing().setThisFourthThing(); // Compile error
        obj.SetThis().SetThat().Cast<MyClass>().SetThisThirdThing().setThisFourthThing();
    }
}

class SuperClass
{
    public SuperClass SetThat()
    {
        return this;
    }

    public T Cast<T>() where T : SuperClass
    {
        return (T)this;
    }
}

class MyClass : SuperClass
{
    public MyClass SetThis()
    {
        return this;
    }

    public MyClass SetThisThirdThing()
    {
        return this;
    }

    public MyClass setThisFourthThing()
    {
        return this;
    }
}