从单个方法返回不同类型的数据

时间:2014-12-10 12:32:59

标签: c#

我正试图找到一种方法来简化一些代码,我希望从一种方法获取具有不同结构的数据。

我有以下代码:

public class VmOne
{
    private ObservableCollection<Structure1> GetFirstStructCollection()
    {
        var myList = new List<Structure1>();
        myList.Add(new Structure1
        {
            Id = 1,
            Name = "John Doe",
            Description = "struct 1 test"
        });

        myList.Add(new Structure1
        {
            Id = 2,
            Name = "Sally Doe",
            Description = "struct 1 test"
        });

        return new ObservableCollection<Structure1>(myList);
    }

    private ObservableCollection<Structure2> GetSecondStructCollection()
    {
        var myList = new List<Structure2>();
        myList.Add(new Structure2
        {
            Id = 1,
            Name = "Saphire Doe",
            Description = "struct 2 test"
        });

        myList.Add(new Structure2
        {
            Id = 2,
            Name = "Onyx Doe",
            Description = "struct 2 test"
        });

        return new ObservableCollection<Structure1>(myList);
    }

    // this wont work....
    public ObservableCollection<object> GetDataByIndex(int pIndex)
    {
        ObservableCollection<object> data;

        if (pIndex == 1)
        {
            data = GetFirstStructCollection();      
        }

        if (pIndex == 2)
        {
            data = GetSecondStructCollection();
        }
        return data;
    }
}

调用
public class MyMain
{

    public void DoSomething()
    {
        var job = new VmOne();

        var data = job.GetDataByIndex(1);

        // .... do something useful with the data
    }
}

我无法找到办法做到这一点。可以这样做吗?只需要一点方向。

数据的使用如下,用户选择他们希望维护的学科。每个学科可以有2个或更多与之关联的数据表。他们可以单步执行数据表来执行维护。每张桌子都有自己独特的结构。我想使用一个通用的UI,这样他们只需要选择一个将加载适当的表来维护的规程。

为了做到这一点,我在数组中有表名,当他们从下拉列表中选择时,索引将指向具有表名的数组。然后我想使用索引或表名来调用我的方法来返回数据集合。由于这是一个WPF应用程序,因此数据将在ObservableCollection中返回。

因此该方法将返回ObservableColleciton类型的任意组合....

4 个答案:

答案 0 :(得分:2)

我认为你不能按照你想要的方式去做。 如果你定义一个类(t)(vb)或类(c#),那么你可以创建一个方法dosomething,然后给你一个通用的东西。

我建议定义一个接口,即structure1和structure2实现,并让你的函数返回你的接口的observablecollection。

欢呼声

答案 1 :(得分:0)

你可以尝试沿着这些方向尝试一些东西,虽然你的规格含糊不清,但有点不清楚:

void Main()
{
   // call it
   VmOne vmOne = new VmOne();
   vmOne.GetDataByIndex<Structure1>(GetStructCollection<Structure1>());

   // ...
}

// Define other methods and classes here
public class VmOne
{
     public ObservableCollection<TStruct> GetStructCollection<TStruct>() where TStruct : class //     or base class for the structures if you can do it
    {
        var myList = new List<TStruct>();
       // add to list somehow
       return new ObservableCollection<TStruct>(myList);
     }

    public ObservableCollection<TStruct> GetDataByIndex<TStruct>(System.Action getStructCollection) where TStruct : class
    {
         ObservableCollection<TStruct> data = getStructCollection<TStruct>();   

        // ...

        return data;
     }
}

请记住,这只是您可以尝试做的草图

答案 2 :(得分:0)

你是关于varianza的吗? ObservableCollection<T>不是共同的,这意味着您可以传递一个ObservableCollection<Tk>,其中Tk是从T继承的。请注意,您可以使用数组执行此操作。

object[] data1 = new Structure1[0];  // is valid becuase array are covariant
ObservableCollection<Structure> data2 = new ObservableCollection<Structure1>();  // compilation error becuase ObservableCollection are not covariant

您可以使用数组,并像这样创建ObservableCollection<object>

private Structure1[] GetFirstStructCollection()
    {
        return new[]
        {
            new Structure1
            {
                Id = 1,
                Name = "John Doe",
                Description = "struct 1 test"
            },
            new Structure1
            {
                Id = 2,
                Name = "Sally Doe",
                Description = "struct 1 test"
            }
        };
    }

    private Structure2[] GetSecondStructCollection()
    {
        return new[]
        {
            new Structure2
            {
                Id = 1,
            Name = "Saphire Doe",
            Description = "struct 2 test"
            },
            new Structure2
            {
                Id = 2,
            Name = "Onyx Doe",
            Description = "struct 2 test"
            }
        };
    }

        public ObservableCollection<object> GetDataByIndex2(int pIndex)
        {
            ObservableCollection<object> data = null;
            if (pIndex == 1)
            {
                data = new ObservableCollection<object>(GetFirstStructCollection());
            }

            if (pIndex == 2)
            {
                data = new ObservableCollection<object>(GetSecondStructCollection());
            }
            return data;
        }

答案 3 :(得分:0)

您可以使用泛型执行类似于您想要的操作:

class Zoo
    {
        public ObservableCollection<T> GetData<T>() where T : class
        {
        if (typeof(T) == typeof(Cat))
            return new ObservableCollection<T>(this.GetCatCollection().Cast<T>().ToList());
            // or:
            // return new ObservableCollection<T>(Cat.GetDefaultCollection().Cast<T>().ToList());

        if (typeof(T) == typeof(Dog))
            return new ObservableCollection<T>(Dog.GetDefaultCollection().Cast<T>().ToList());

        if (typeof(T) == typeof(Lion))
            return new ObservableCollection<T>(Lion.GetDefaultCollection().Cast<T>().ToList());

        return null;

        // pseudo-switch version
        //ObservableCollection<T> result = null;

        //var @switch = new Dictionary<Type, Action> {
        //{ typeof(Cat), () => result = new ObservableCollection<T>(Cat.GetDefaultCollection().Cast<T>().ToList()) },
        //{ typeof(Dog), () => result =  new ObservableCollection<T>(Dog.GetDefaultCollection().Cast<T>().ToList())},
        //{ typeof(Lion), () => result = new ObservableCollection<T>(Lion.GetDefaultCollection().Cast<T>().ToList())}};

        //@switch[typeof(T)]();

        //return result;
    }

    private ObservableCollection<Cat> GetCatCollection()
    {
            ObservableCollection<Cat> list = new ObservableCollection<Cat>();
            list.Add(new Cat { CatName = "Cat No. 1" });
            list.Add(new Cat { CatName = "Cat No. 2" });
            list.Add(new Cat { CatName = "Cat No. 3" });
            return list;
    }

}

class Cat
{
    public string CatName { get; set; }

    public static ObservableCollection<Cat> GetDefaultCollection()
    {
        ObservableCollection<Cat> list = new ObservableCollection<Cat>();
        list.Add(new Cat { CatName = "Cat No. 1" });
        list.Add(new Cat { CatName = "Cat No. 2" });
        list.Add(new Cat { CatName = "Cat No. 3" });
        return list;
    }
}

class Dog
{
    public string DogName { get; set; }

    public static ObservableCollection<Dog> GetDefaultCollection()
    {
        ObservableCollection<Dog> list = new ObservableCollection<Dog>();
        list.Add(new Dog { DogName = "Dog No. 1" });
        list.Add(new Dog { DogName = "Dog No. 2" });
        list.Add(new Dog { DogName = "Dog No. 3" });
        return list;
    }
}
class Lion
{
    public string LionName { get; set; }

    public static ObservableCollection<Lion> GetDefaultCollection()
    {
        ObservableCollection<Lion> list = new ObservableCollection<Lion>();
        list.Add(new Lion { LionName = "Lion No. 1" });
        list.Add(new Lion { LionName = "Lion No. 2" });
        list.Add(new Lion { LionName = "Lion No. 3" });
        return list;
    }
}

使用示例:

    var zoo = new Zoo();

    ObservableCollection<Cat> cats = zoo.GetData<Cat>();
    ObservableCollection<Dog> dogs = zoo.GetData<Dog>();
    ObservableCollection<Lion> lions = zoo.GetData<Lion>();


    Console.WriteLine("-------------- Cats:");
    cats.ToList().ForEach(cat => Console.WriteLine(cat.CatName));
    Console.WriteLine("-------------- Dogs:");
    dogs.ToList().ForEach(dog => Console.WriteLine(dog.DogName));
    Console.WriteLine("-------------- Lions:");
    lions.ToList().ForEach(lion => Console.WriteLine(lion.LionName));

结果:

-------------- Cats:
Cat No. 1
Cat No. 2
Cat No. 3
-------------- Dogs:
Dog No. 1
Dog No. 2
Dog No. 3
-------------- Lions:
Lion No. 1
Lion No. 2
Lion No. 3