我可以在C#中的相同基本类型的多个列表上使用通用的getter / setter方法吗

时间:2018-10-24 22:31:19

标签: c# list class generics member

我想知道是否可以为以下代码创建通用的getter和setter方法。

当前,设置器将检查输入对象的实际类型,并将其添加到相关列表中。这对我来说似乎是一种不好的方法,但是我想知道是否有更好的方法。

我不能使用字典等其他任何数据结构,因为我使用的序列化系统只能序列化简单的集合类型(如列表和数组),因此只能序列化所有单独的列表。

public abstract class BaseStyleType {}
public class ImageStyle  : BaseStyleType {}
public class TextStyle   : BaseStyleType {}
public class ButtonStyle : BaseStyleType {}
//...etc

public class GlobalStyle : ASerializedObject
{
    public List<ImageStyle>  ImageStyles     = new List<ImageStyle>();
    public List<TextStyle>   TextStyles      = new List<TextStyle>();
    public List<ButtonStyle> ButtonStyles    = new List<ButtonStyle>();
    //... etc

    // Setter
    public void SetStyle(BaseStyleType inStyle)
    { 
        if (inStyle as ImageStyle != null)
            ImageStyles.Add((ImageStyle)inStyle);
        else if (inStyle as TextStyle != null)
            TextStyles.Add((TextStyle)inStyle);
        else if (inStyle as ButtonStyle != null)
            ButtonStyles.Add((ButtonStyle)inStyle);
        //... etc
    }

    // Getter
    public T GetStyle<T>(int index)
    {
        //...?
    }
}

谢谢

2 个答案:

答案 0 :(得分:1)

仅仅是因为您不能将事物用于序列化目的,所以不应阻止您实际使用它们。

以下解决方案的优点是,您可以从BaseStyleType(或其他超级类型)无限创建派生类,而只需创建属性即可访问字典。

public abstract class BaseStyleType {}
public class ImageStyle  : BaseStyleType {}
public class TextStyle   : BaseStyleType {}
public class ButtonStyle : BaseStyleType {}

// NOT THREAD SAFE
public class GlobalStyle
{
   // 
   private Dictionary<Type,List<BaseStyleType>> _lists = 
     new Dictionary<Type,List<BaseStyleType>>();

   // Not sure why you'd use Fields here...
   public IEnumerable<ImageStyle> ImageStyles
   {
     get 
     {
       IEnumerable<ImageStyle> result = null;
       List<BaseStyleType> list;
       if (_lists.TryGetValue(typeof(ImageStyle), out list))
       {
         result = list.Cast<ImageStyle>();
       }
       return result;
     }
   }
   //etc
   //public List<ImageStyle>  ImageStyles     = new List<ImageStyle>();
   //public List<TextStyle>   TextStyles      = new List<TextStyle>();
   //public List<ButtonStyle> ButtonStyles    = new List<ButtonStyle>();


   // Setter
   public void SetStyle<T>(T inStyle)
       where T : BaseStyleType
   {
       List<BaseStyleType> list;
       if (_lists.TryGetValue(typeof(T), out list))
       {
         list.Add(inStyle);
       }
       else
       {
           list = new List<BaseStyleType>();
           list.Add(inStyle);
           _lists.Add(typeof(T), list);
       }
   }
}

答案 1 :(得分:0)

我至少看到两种方式:

1)您拥有一个简单而扁平的等级制。仅列出BaseStyleType。让协方差和自动向上转换处理细节。

2)像这样修改代码:

public abstract class BaseStyleType {}
public class ImageStyle  : BaseStyleType {}
public class TextStyle   : BaseStyleType {}
public class ButtonStyle : BaseStyleType {}
//...etc

public class GlobalStyle <List1Type, List2Type, List3Type, ... > : ASerializedObject
{
    public List<List1Type>  ImageStyles     = new List<List1Type>();
    public List<List2Type>   TextStyles      = new List<List2Type>();
    public List<List3Type> ButtonStyles    = new List<List3Type>();
    //... etc

    // Setter
    public void SetStyle(BaseStyleType inStyle)
    { 
        if (inStyle as ImageStyle != null)
            ImageStyles.Add((ImageStyle)inStyle);
        else if (inStyle as TextStyle != null)
            TextStyles.Add((TextStyle)inStyle);
        else if (inStyle as ButtonStyle != null)
            ButtonStyles.Add((ButtonStyle)inStyle);
        //... etc
    }

    // Getter
    public T GetStyle<T>(int index)
    {
        //...?
    }
}

长类型列表的问题是,您最终不得不使用像 每GlobalStyle <ImageStyle , TextStyle, ButtonStyle>都需要一种类型(字段类型,返回类型,参数等)。从两个通用占位符开始,通常最好创建一个类型别名。

using CustomGlobalStyle = GlobalStyle <ImageStyle, TextStyle, ButtonStyle>;