可以使用C#Generic Class字段

时间:2014-08-20 12:24:23

标签: c# generics

我是C#(Java开发人员)的新手,我希望有一个类通用列表的类字段,实际上它是一个列表字典:

protected IDictionary<String, IList<Object>> filters;

我有设置

的代码
public void SetFilters(String key, params Object[] values) {
    if (key == null || values == null) {
        throw new ArgumentNullException("Must have filter name and values.");
    }
    if (filters == null) filters = new Dictionary<String, IList<Object>>();
    IList<Object> fvalues = values.ToList();
    filters.Add(key, fvalues);         
}

但是当我的代码尝试检索并将IList<Object>强制转换回IList<String>IList<int>时,我收到了InvalidCastException。

我以为我会把这个列表变得通用:

protected IDictionary<String, IList<T>> filters; //does not complile

protected IDictionary<String, IList<T>> filters  where T: Object;//does not compile either

我不能使该类具有通用性,因为字典将包含Stringsint的列表。在Java中,IntegerStrings都是Objects,因此这不是IList<? extends Object>的问题。

谢谢!

3 个答案:

答案 0 :(得分:2)

您可以使用System.Collection.IList,类似于:

public class Foo
{
    public IDictionary<String, IList> filters;
    public void SetFilters(String key, params object[] values)
    {
        if (key == null || values == null)
        {
            throw new ArgumentNullException("Must have filter name and values.");
        }

        if (filters == null)
        {
            filters = new Dictionary<String, IList>();
        }

        IList fvalues = values.ToList();
        filters.Add(key, fvalues);
    }
}

然后您可以像这样使用它:

var foo = new Foo();

foo.SetFilters("Key1", 1,2,3);
foo.SetFilters("Key2", "a","b","c");
foo.SetFilters("Key3", new {a = 1, b = 2}, new {c = 1, d = 2});

在访问和使用它时,您仍然遇到将每个列表类型转换回预期类型的​​问题。


DEMO - 使用IList


答案 1 :(得分:0)

有帮助吗?我创建了一个新的泛型类。

internal class Program
{
    private class Reed<T>
    {
        private IDictionary<String, IList<T>> filters;
        public void SetFilters(String key, params T[] values)
        {
            if (key == null || values == null)
            {
                throw new ArgumentNullException("Must have filter name and values.");
            }

            if (filters == null)
                filters = new Dictionary<String, IList<T>>();
            IList<T> fvalues = values.ToList();
            filters.Add(key, fvalues);
        }
    }

    private static void Main(string[] args)
    {
        var r1 = new Reed<string>();
        r1.SetFilters("test", "one", "two", "three");
        var r2 = new Reed<int>();
        r2.SetFilters("test", 1, 2, 3);
    }
}

答案 2 :(得分:0)

为了避免错误转换,您需要首先创建一个类型化列表。要做到这一点,你应该使用通用。

对于字典项类型,您可以使用IList或object,但是您需要将强类型列表存储为项值。

如果您将SetFilters设为通用方法,那么它可以将正确键入的列表存储在字典中。我包含了一个GetFilters方法,它返回与键匹配的列表。即values.ToList()将创建一个List<T>

public class FilterManager
{
    protected IDictionary<String, IList> filters = new Dictionary<string, IList>();

    public void SetFilters<T>(String key, params T[] values)
    {
        if (key == null || values == null)
        {
            throw new ArgumentNullException("Must have filter name and values.");
        }

        IList fvalues = values.ToList();
        filters.Add(key, fvalues);
    }

    public IList<T> GetFilters<T>(string key)
    {
        return (IList<T>)filters[key];
    }
}

像这样称呼

var filterManager = new FilterManager();
filterManager.SetFilters("MyIntegerFilters", 3, 4, 5);
filterManager.SetFilters("MyStringFilters", "A", "B", "C");

var intFilters = filterManager.GetFilters<int>("MyIntegerFilters");
var stringFilters = filterManager.GetFilters<string>("MyStringFilters");

如果你打电话

,你会得到一个例外
var filters = filterManager.GetFilters<int>("MyStringFilters");

因为它会尝试将List<string>转换为List<int>