如何在C#中链接方法时进行强制转换
本文关键字:转换 方法 链接 | 更新日期: 2023-09-27 18:09:38
我正在尝试编码一些东西,我总是返回对象本身,这样我就可以继续链接了。像这个
object.SetThis().SetThat().SetThisThirdThing().setThisFourthThing();
我在所有的方法中都返回了这个,这样我就可以继续这样做了。但是我的一个方法是我在基类中创建的,当然它会返回基类。
因此,它返回的不是public MyClass SetThat()
,而是public SuperClass SetThat()
。因为它返回SuperClass
而不是MyClass
,所以我不能调用SetThisThirdThing()
,因为基类不知道它
那么我该如何铸造才能保住链子呢?语法是什么?我试过
object.SetThis().(MyClass)SetThat().SetThisThirdThing().setThisFourthThing();
或者有没有一种方法可以让superClass方法在从子类调用时返回子类,而不必在所有子类中重写它?
这是所有子类的共同点之一,所以如果我能够以某种方式绕过它,而不必在所有子类中覆盖它,那就太好了。
有没有一种方法可以让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
var obj = ((MyType)myObject.SetThis()).SetThat();
p.S你应该避免那样做,因为读起来会很困惑。
若要强制转换(子(表达式,需要将类名放在前面(并使用括号(。
((MyClass)obj.SetThis().SetThat()).SetThisThirdThing().setThisFourthThing();
(注意,object
是一个保留字,因此不能将其用作变量名(
另一种选择是使用as
关键字:
(obj.SetThis().setThat() as MyClass).SetThisThirdThing().setThisFourthThing();
注意,如果setThat()
不返回MyClass
,则这将表现不同;第一个版本将抛出InvalidCastException
,第二个版本抛出NullReferenceException
,因为如果不能进行强制转换,as
将返回null
。
这样尝试:
((MyClass)object.SetThis().SetThat()).SetThisThirdThing()
只需使用括号:
(MyClass)(object.SetThis().SetThat()).SetThisThirdThing().setThisFourthThing();
我不知道为什么object
在那里,但你可以安全地把它取下来。
(MyClass)(SetThis().SetThat()).SetThisThirdThing().setThisFourthThing();
在不修改类的情况下,您还可以编写类似的扩展方法As
public static T As<T>(this MyBaseClass obj) where T : MyBaseClass
{
return (T)obj;
}
--
用途与此类似
new MyChildClass().SetBase().As<MyChildClass>().SetThis();
为什么不这样做?一个简单的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;
}
}