Getter和Setter在通用界面中 - 这可能吗?

时间:2011-06-10 19:34:50

标签: c# generics

还在学习C#泛型的方法......是否有可能实现这一功能?

public interface ISetting<T>
{
    void SetSettings(T obj);
    // myTypeHere GetSettings(T obj);
}

public class RadDockSetting : ISetting<CormantRadDock>
{
    public RadDockSetting()
    {
    }

    public RadDockSetting GetSettings(CormantRadDock dock)
    {
    }

    public void SetSettings(CormantRadDock dock)
    {
    }
 }

我意识到这是一种使用Getter的反直觉方式 - 不应该传递任何东西。我正在做的是创建一个对象RadDockSetting,它存储CormantRadDock的相关属性 - 然后返回'got'设置。

GetSettings 当前是一个静态方法,但我意识到这需要重构,以便允许从接口实现一个getter。也许一旦发生这种情况,吸气剂的“古怪”就会消失?

所以,关于所有这些的一点背景:

我从一个有很多“复制/粘贴”功能的课开始。这些功能负责保存和删除管理员的控制。当我意识到这一点时,我开始尝试使这些功能更通用。在SO的帮助下,我成功地删除了泛型。

供参考,这里是删除:

public static void Remove<T>(string controlID) where T: new()
{
    Logger.InfoFormat("Removing control {0}", controlID);
    T states = RadControlStates.GetStates<T>();
    (states as IDictionary).Remove(controlID);
    RadControlStates.SetStates<T>(states);
}

它的调用方式如下:RadControlSave.Remove<SerializableDictionary<string, RadPaneSetting>>(ID);

现在,我试图将这种通用性扩展到其他方法 - 储户。以下是其中一种方法的目前情况:

public static void SavePane(CormantRadPane pane)
{
    Logger.InfoFormat("Saving pane {0}", pane.ID);
    RadPaneSetting paneSettings = RadPaneSetting.GetSettings(pane);
    SerializableDictionary<string, RadPaneSetting> paneStates = RadControlStates.GetStates<SerializableDictionary<string, RadPaneSetting>>();

    bool paneIsKnown = paneStates.ContainsKey(paneSettings.ID);

    if (paneIsKnown)
    {
        Logger.Debug("Pane is known. Overwriting data.");
        paneStates[paneSettings.ID] = paneSettings;
    }
    else
    {
        Logger.Debug("Pane is unknown. Saving data.");
        paneStates.Add(paneSettings.ID, paneSettings);
    }

    RadControlStates.SetStates<SerializableDictionary<string, RadPaneSetting>>(paneStates);
}

在此代码块的开头,调用“RadPaneSetting.GetSettings(窗格)”。

RadPaneSettings实现了ISettings接口。这是使用ISetting的二传手。

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

5 个答案:

答案 0 :(得分:4)

看起来你只需要在这里添加另一个通用参数

public interface ISetting<T1, T2>
{
    void SetSettings(T1 obj);
    T2 GetSettings(T1 obj);
}

public class RadDockSettings : ISetting<CormantRadDock, RadDockSetting>

答案 1 :(得分:4)

您的问题不是很清楚但是您需要一个属性:

public interface ISetting<T>
{
    T Setting { get; set; }
}

public class RadDockSetting : ISetting<CormantRadDock>
{
    public CormantRadDock Setting { get; set; }
}

答案 2 :(得分:1)

如果定义另一个通用参数(如@jaredPar指出的那样),你会得到什么。但是,您可能需要考虑使用扩展方法而不是类方法。它将允许您使用“更干净”的API来获取设置。

样品:

public static class RadDockExtensions
{
    public static RadDockSetting GetSettings(this CormantRadDock dock)
    {
        // Implementation
    }
}

或者如果你想要更通用的东西

public static class RadDockExtensions
{
    public static U GetSettings<T,U>(this T dock)
    {
        // Implementation
    }
}

虽然在这种情况下你需要添加一些约束来实际创建实现

我并不完全清楚SetSettings方法的用途是什么,因为您似乎在发送给GetSettings的同一对象中发送。

在这两种情况下,您都可以使用上面的代码:

RadDockSetting mySettings = myDock.GetSettings();

答案 3 :(得分:0)

嗯,可能已经错过了这一点。

但为什么设置类会调用getSettings?它会回归this吗?

set使用dock来初始化实例,然后get只是实例。

答案 4 :(得分:0)

我不确定你想做什么。 也许一个扩展方法可以做到这一点,而不是界面内部的一个方法ISetting ......就像那样:

public static T GetSettings<T,C>(this T t, C c) where T : ISetting<C>
{
    return t;
}

希望这会有所帮助......