返回父方法中的子类型的泛型方法

本文关键字:泛型方法 类型 方法 返回 | 更新日期: 2023-09-27 17:51:02

我已经在c#中尝试了几个星期的扩展方法,并且我遇到了一些有趣的事情。我尝试为我的dto构建泛型,如下所示:

public class ParentDto{
    public string attrStr{get;set;}
}
public static class ParentDtoExtensions{
    public static T AttrStr<T>(this T parentDto, string attrStr)
    where T:ParentDto{
        parentDto.attrStr = attrStr;
        return parentDto;
    }
}

然后在子类中:

public class ChildDto:ParentDto{
    public string childAttrStr{get;set;}
}
public static class ChildDtoExtensions{
    public static T ChildAttrStr<T>(this T childDto, string childAttrStr)
    where T:ChildDto{
        childDto.childAttrStr = childAttrStr;
        return childDto;
    }
} 

然后让我像这样链接我的方法:

return ((new ChildDto()).AttrStr("someString").ChildAttrStr("someOtherString"));

这真的很吸引我。能够让单单元设置器以及其他方法返回调用类型对于链接代码块非常方便。

然而,我希望能够将setter方法集成到我认为它们真正属于的父类中,同时保持上面所示的现有代码流,但我不知道如何实现返回实现类的子类的方法。比如:

public class ParentDto{
    public string attrStr{get;set;}
    public T AttrStr<T>(string attrStr)
    where T:ParentDto{
        parentDto.attrStr = attrStr;
        return parentDto;
    }
}

但是这不起作用,因为编译器(?)不知道调用类型。有人知道怎么做吗?

请记住,我不是在寻找关于我现有实现的代码气味的建议,因为我确信有更多的C# -ish方法来实现这个

返回父方法中的子类型的泛型方法

您可以做以下事情,但在我看来您的扩展方法要好得多:

public class ParentDto<T> where T : ParentDto<T> {
    public string attrStr{get;set;}
    public T AttrStr(string attrStr) {
        this.attrStr = attrStr;
        return (T)this;
    }
}
public sealed class ChildDto : ParentDto<ChildDto> {
    public string childAttrStr{get;set;}
    public ChildDto ChildAttrStr(string childAttrStr) {
        this.childAttrStr = childAttrStr;
        return this;
    }
}

有关此模式的更多信息以及为什么您应该尽可能避免它,请参阅Eric Lippert的博客文章,curouser and curouser。

也就是说,我同意这是一种代码气味;您可能应该只使用属性设置器,而不是使用流畅的语法。但既然你不是在征求意见,我就不讨论了。

如果你所做的只是在一个新对象上设置属性,那么你可以使用对象初始化器来代替:

return new ChildDto()
    {
        attrStr = "someString",
        childAttrString = "someOtherString"
    }