开发者

Getter and Setter in generic interface - is this possible?

Still learning my ways around C# generics... is it possible to achieve this functionality?

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)
    {
    }
 }

I realize this is a counter-intuitive way to be using a Getter -- shouldn't have to pass anything to it. What I'm doing is creating an object, RadDockSetting, that stores the relevant properties of the CormantRadDock -- and then returns the 'got' settings.

GetSettings is currently a static method, but I realize this will need to be refactored in order to allow implementing a getter from the interface. Maybe once this occurs the 'weirdness' of the getter will fall away?

So, a little background on all of this:

I started with a class that had a lot of 'copy/pasted' functions. These functions were in charge of saving and removing controls from a manager. When I realized this I set out trying to make these functions more generic. I succeeded, with SO's help, in making remove generic.

For reference, here is remove:

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

and it is called like so: RadControlSave.Remove<SerializableDictionary<string, RadPaneSetting>>(ID);

Now, I am trying to extend this genericness to the rest of the methods -- the savers. Here's how one of these methods looks currently:

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

At the start of this code block there is a call to "RadPaneSetting.GetSettings(pane)".

RadPaneSettings implements the ISettings interface. Here is ISetting's setter being used.

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


It looks like you just need to add another generic parameter here

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

public class RadDockSettings : ISetting<CormantRadDock, RadDockSetting>


Your question is not very clear but do you need a property:

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

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


What you have would work if you define another generic parameter (as @jaredPar pointed out). You may want to consider using Extension Methods rather than the class approach, though. It would allow you to have a "cleaner" API for getting the settings.

Sample:

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

Or if you want something more generic

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

Though in this case you would need to add some constraints to actually create the implementation

It's not entirely clear to me what the purpose of the SetSettings method is, since you appear to be sending in the same object your sending to GetSettings.

In both cases you would use the above code like this:

RadDockSetting mySettings = myDock.GetSettings();


hmmmm might have missed the point.

but why would a settings class have a getSettings call? would it just return this?

The set takes a dock to initialise the instance, then get is merely the instance.


I'm not really sure what you want to do. Maybe an extension method could do the trick rather than a method inside the interface ISetting... something like that :

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

Hope this helps...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜