如何将通用或对象参数转换为引用类型

时间:2016-05-19 16:48:43

标签: c#

在这种情况下,我无法为TypeA和TypeB创建基本类型,因此我无法在方法上添加Where:TypeBase。我想看看是否有另一种解决方法。

class TypeA
{
    int number;
    string someString;
}

class TypeB
{
    int number;
    decimal someDecimal;
}

private List<int> Test(object inputs)
{
    List<int> rv = new List<int>();

    if (inputs is List<TypeA>)
        inputs = (List<TypeA>)inputs;
    else if(inputs is List<TypeB>)
        inputs = (List<TypeB>)inputs;

    foreach(item in inputs)
    {
        rv.Add(item.number);
    }
    return rv;
}

3 个答案:

答案 0 :(得分:1)

private void GenericTest<T>(IEnumerable<T> inputs)
{
    MethodInfo property = typeof(T).GetProperty(/*YOUR PROPERTY*/).GetMethod;
    foreach (var input in inputs)
    {
        object value = property.Invoke(input, null);
        // Logic
    }
}

// To protect it from error
public void Test(IEnumerable<TypeA> inputs)
{
    GenericTest(inputs);
}

// To protect it from error
public void Test(IEnumerable<TypeB> inputs)
{
    GenericTest(inputs);
}

顺便说一下为什么不将属性名称传递给Test方法?

答案 1 :(得分:0)

您可以将其投放到IEnumerable,然后执行foreach - 循环:

private void Test(object inputs)
{
    // you can also change the parameter to IEnumerable to take advantage of compile-time type-checking.
    var items = inputs as IEnumerable;
    if (items == null)
        throw new ArgumentException("inputs");

    foreach (var item in items)
    {

    }
}

如果每个类的逻辑需要不同,请使用:

private void Test(object inputs)
{
    var typeAs = inputs as IEnumerable<TypeA>;
    if (typeAs != null)
    {
        foreach (var item in typeAs)
        {

        }
        return;
    }
    var typeBs = inputs as IEnumerable<TypeB>;
    if (typeBs != null)
    {
        foreach (var item in typeBs)
        {

        }
        return;
    }

    throw new ArgumentException("inputs");
}

答案 2 :(得分:0)

如果你单独迭代它们,你将不会做任何额外的工作:

class Program
{
    private void Test(object inputs)
    {
        if (inputs is List<TypeA>)
            loop((List<TypeA>) inputs);
        if (inputs is List<TypeB>)
            loop((List<TypeB>)inputs);
    }

    private void loop(IEnumerable<TypeA> inputs)
    {
        foreach (var input in inputs)
        {
            logic(input.i);
        }
    }

    private void loop(IEnumerable<TypeB> inputs)
    {
        foreach (var input in inputs)
        {
            logic(input.i);
        }
    }

    private void logic(int i)
    {
        // magic happens here
    }
}

class TypeA
{
    public int i;
}

class TypeB
{
    public int i;
}

但是,对于世界上所有善的人的爱,请不要这样做。

如果您真的必须出于某种原因一次遍历列表,并且知道只会使用TypeAs和TypeB调用Test,则可以使用dynamic type处理此问题:

class Program
{
    static void Main(string[] args)
    {
        var w = new TypeA {i = 8};
        var x = new TypeA {i = 16};
        var y = new TypeB {i = 32};
        var z = new TypeC(); // don't pass this to Test!
        var l = new List<dynamic> {w, x, y};
        Test(l);
    }

    private static void Test(IEnumerable<dynamic> inputs)
    {
        foreach (var input in inputs)
        {
            logic(input.i);
        }
    }

    private static void logic(int i)
    {
        // magic happens here
    }
}

class TypeA
{
    public int i;
}

class TypeB
{
    public int i;
}

class TypeC {} // no members