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

本文关键字:同类型 数据 返回 单个 方法 | 更新日期: 2023-09-27 18:33:46

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

我有以下代码:

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 应用程序,因此数据在可观察集合中返回。

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

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

我认为你不能按照你正在寻找的方式做到这一点。如果你定义了一个类(t((vb(oder class(c#(,那么你可以创建一个方法dosomething,然后给你一个通用的东西。

我建议定义一个接口,结构 1 和结构 2 确实实现了,并让你的函数返回接口的可观察集合。

干杯

你也许可以尝试一些类似的东西,尽管你的规格很模糊,有点不清楚:

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

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

你是关于瓦里安扎的吗? 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;
        }

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

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