扩展方法和泛型 - 我该怎么做?

时间:2011-06-10 20:54:56

标签: c# generics refactoring

我正在检修一些代码,我遇到了一些障碍。

这是我目前拥有的方法,它需要重新加工以支持一些结构更改:

/// <summary>
/// Recreates a dashboard control based off of its settings.
/// </summary>
/// <typeparam name="T"> The type of control to be recreated. </typeparam>
/// <param name="settings"> The known settings needed to recreate the control.</param>
/// <returns> The recreated control. </returns>
public static T Recreate<T>(ISetting<T> settings) where T : new()
{
    T _control = new T();
    settings.SetSettings(_control);
    Logger.DebugFormat("Recreated control {0}", (_control as Control).ID);
    return _control;
}

正在完全删除ISetting,以支持_control已知的扩展方法。

所以,我现在有:

public static class RadControlExtensions
{
    public static RadDockZoneSetting GetSettings(this RadDockZone dockZone)
    {
        RadDockZoneSetting radDockZoneSetting = new RadDockZoneSetting(dockZone.UniqueName, dockZone.ID, dockZone.Skin, dockZone.MinHeight, 
            dockZone.HighlightedCssClass, dockZone.BorderWidth, dockZone.Parent.ID);

        return radDockZoneSetting;
    }

    public static RadTabSetting GetSettings(this RadTab tab, int index)
    {
        RadTabSetting radTabSetting = new RadTabSetting(tab.Text, tab.Value, index);
        return radTabSetting;
    }

    //Continued
}

正在重新创建的控件保证具有此扩展方法(不过可以很好地强制执行此操作。)

我现在在:

public static T Recreate<T>() where T : new()
{
    T _control = new T();
    //Not right -- you can't cast a control to an extension method, obviously, but
    //this captures the essence of what I would like to accomplish.
    (_control as RadControlExtension).SetSettings();
    Logger.DebugFormat("Recreated control {0}", (_control as Control).ID);
    return _control;
}

如果可能的话,我应该考虑如何支持这一点?

4 个答案:

答案 0 :(得分:0)

如果您知道传递的每个_control将是RadDockZone(或从RadDockZone派生),请执行以下操作:

T _control = new T();
(RadDockZone)_control.SetSettings();
Logger.DebugFormat("Recreated control ... //rest of code here

如果它不总是RadDockZone,你需要进行一些类型检查以获得正确的类型来调用扩展方法。我假设你在可以传递给Recreate方法的所有可能的类型上都有.SetSettings()扩展方法。

答案 1 :(得分:0)

您需要将T转换为扩展方法支持的内容。

(_control as RadDockZone).GetSettings

扩展方法对传统意义上不属于某种类型的类型进行操作。 'SomeFn(string this)'使你的扩展可以处理字符串和字符串以及从它们派生的任何东西。

答案 2 :(得分:0)

如果我理解你要做的是什么,只需在T上加上约束:

public static T Recreate<T>() where T : RadControl, new() {
    // etc.
}

您可能必须使用双重调度并定义

public static RadControl GetSettings(this RadControl control) {

}

将调用相应的GetSettings方法。

答案 3 :(得分:0)

不,杰森的答案是更清洁的方式。接受的解决方案杀死了类型安全性并且使用泛型毫无意义。您可以切换到无通用设计(具有RadControlFactory)并完成工作。