简体   繁体   English

扩展方法和 generics - 我应该怎么做?

[英]Extension Methods and generics - How should I be doing this?

I'm in the middle of overhauling some code and I hit a bit of a snag.我正在大修一些代码,但遇到了一些障碍。

This is the method which I currently have, it needs reworking to support some structure changes:这是我目前拥有的方法,它需要重新设计以支持一些结构更改:

/// <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 is being removed completely in favor of an extension method known to _control. ISetting 被完全删除,取而代之的是 _control 已知的扩展方法。

So, I have now:所以,我现在有:

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
}

The control that is being recreated is guaranteed to have this extension method (would be nice to enforce this, though.)保证正在重新创建的控件具有此扩展方法(不过,最好强制执行此方法。)

I'm now at:我现在在:

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;
}

What should I be looking into to support this, if possible?如果可能的话,我应该研究什么来支持这一点?

If you know that every _control that gets passed will be a RadDockZone (or derived from RadDockZone) just do this:如果您知道通过的每个_control都将是 RadDockZone(或派生自 RadDockZone),请执行以下操作:

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

If it's not always going to be a RadDockZone, you'll need to do some type checking to get the right type to call the extension method.如果它并不总是 RadDockZone,则需要进行一些类型检查以获取正确的类型来调用扩展方法。 I'm presuming, there, that you have a.SetSettings() extension method on all the possible Types that could be passed to your Recreate method.我假设您在所有可能的类型上都有一个 .SetSettings() 扩展方法,这些类型可以传递给您的 Recreate 方法。

You need to cast your T to something that is supported by your extension method.您需要将您的 T 转换为您的扩展方法支持的东西。

(_control as RadDockZone).GetSettings

Extension methods operate on a type they are not a type in the traditional sense.扩展方法对一种类型进行操作,它们不是传统意义上的类型。 The 'SomeFn(string this)' makes your extension work on things that are strings which would be strings and anything derived from them. 'SomeFn(string this)' 使您的扩展程序可以处理作为字符串的内容以及从它们派生的任何内容。

If I understand correctly what you are trying to do, just put a constraint on T :如果我正确理解您要做什么,只需对T施加约束:

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

You might have to use double dispatch and define您可能必须使用双重调度并定义

public static RadControl GetSettings(this RadControl control) {

}

which will invoke the appropriate GetSettings method.这将调用适当的GetSettings方法。

No, Jason's answer is the cleaner way to go.不,杰森的答案是 go 的更清洁方法。 The accepted solution killed the type safety and made use of generics pointless.公认的解决方案杀死了类型安全,并毫无意义地使用了 generics。 You could switch to generic-less design (having a RadControlFactory ) and had the job done.您可以切换到无通用设计(具有RadControlFactory )并完成工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM