通用“TThis'的流畅班 [英] Generic 'TThis' for fluent classes

查看:142
本文介绍了通用“TThis'的流畅班的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是构建添加一些特殊的行为流畅的界面,我有一个包含了大量的流畅逻辑的基类和派生类。我现在面临的问题是从派生类型的实例调用时的基类中的流畅方法的返回类型。调用的基类的方法后,只有基类的方法进一步流利调用保持可用。



更改其中的方法被调用将帮助它来编译的命令,但它使得它的可读性这是有点儿为流畅的接口点。有没有一种方法来定义某种这个类型的基类,以便所有方法返回一个类型相同。



示例

$ B $的b

 公共类字段< T> 
{
公共字段< T>名称(字符串名称)
{
_name =名称;
返回这一点;
}
}

公共SpecialField< T> :字段< T>
{
公共SpecialField< T>特殊(){返回此; }
}


//! Arrgh。特别是不实地℃的成员; T>类。
变种specialField =新SpecialField()
.Name点(冰)
。特别();



破解



我试过通过执行类似下面的解决它,但它不是有效的C#:(但至少表达了我怎么想编写的接口。

 公共类字段< T,TThis>:TThis 
式TThis:字段< T,TThis>
{
公共TThis名称(字符串名称){...}
}

公共SpecialField< T>:字段< T,SpecialField< T>>
{
公共TThis特(){返回此;}
}


解决方案

周围的一些其他流利的API,我发现戳如何后做到这一点。这是不是很干净,但效果很好。基本上你引入一个中间基类为您要使用的每个派生类型,并将它传递了TThis类型的实际执行情况。



示例



 公共类FieldBase< T,TThis> 
式TThis:FieldBase< T,TThis>
{
公共TThis名称(字符串名称)
{
_name =名称;
回报(TThis)这一点;
}
}

公共类字段< T> :FieldBase< T,现场< T>> {}

公共类SpecialFieldBase< T,TThis> :FieldBase< T,TThis>
式TThis:SpecialFieldBase< T,TThis>
{
公共TThis特(){回报(TThis)这一点; }
}

公共类SpecialField< T> :SpecialFieldBase< T,SpecialField< T>> {}


//是它的工作原理!
VAR = specialField =新SpecialField()
.Name点(冰)
。特别();


I'm constructing a fluent interface where I have a base class that contains the bulk of the fluent logic, and a derived class that add some specialized behavior. The problem I'm facing is the return type of the fluent methods in the base class when called from an instance of the derived type. After invoking a method of the base class, only methods of the base class remain available for further fluent invocations.

Changing the order in which the methods are invoked will help it to compile, but it makes it less readable which is kinda the point for fluent interfaces. Is there a way to define some sort of "This" type for the the base class so that all methods return the same type.

Example

public class Field<T>
{
    public Field<T> Name( string name )
    {
    	_name = name;
    	return this;
    }
}

public SpecialField<T> : Field<T>
{
    public SpecialField<T> Special(){ return this; }
}


// !!! Arrgh. Special is not a member of the Field<T> class.
var specialField = new SpecialField()
    .Name( "bing" )
    .Special();

Broken Solution

I've tried solving it by doing something like the following but it's not valid C# :( but at least expresses how I'd like to code the interface.

public class Field<T,TThis> : TThis
    where TThis : Field<T,TThis>
{
    public TThis Name( string name ){...}
}

public SpecialField<T> : Field<T,SpecialField<T>>
{
    public TThis Special(){ return this; }
}

解决方案

After poking around some other fluent APIs I found how to do it. It's not quite as clean, but it works well. Basically you introduce an intermediary base class for each derived type that you want to use and it passes the "TThis" type to the actual implementation.

Sample

public class FieldBase<T,TThis> 
    where TThis : FieldBase<T,TThis>
{
    public TThis Name( string name ) 
    {
        _name = name;
        return (TThis)this;
    }
}

public class Field<T> : FieldBase<T,Field<T>>{}

public class SpecialFieldBase<T,TThis> : FieldBase<T,TThis>
    where TThis : SpecialFieldBase<T,TThis>
{
    public TThis Special(){ return (TThis)this; }
}

public class SpecialField<T> : SpecialFieldBase<T,SpecialField<T>>{}


// Yeah it works!
var = specialField = new SpecialField()
    .Name( "bing" )
    .Special();

这篇关于通用“TThis'的流畅班的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆