如何调用Generic T的方法?

时间:2018-02-08 16:54:36

标签: c# class generics

namespace TestingConsole
{
    class Test<TA, TB>
    {
        TA _value1;
        TB _value2;

        public Test(TA t, TB t1)
        {
            _value1 = t;
            _value2 = t1;
        }

        void Write()
        {
            Console.WriteLine("ATest: " + ((ATest)_value1).GetValue());
            // Here I get "type TA cannot be converted to ATest"
        }
    }

    class ATest
    {
        private int x;

        public void SetValue(int y)
        {
            x = y;
        }

        public int GetValue()
        {
            return x;
        }
    }

    class BTest
    {
        private string x;

        public void SetValue(string y)
        {
            x = y;
        }

        public string GetValue()
        {
            return x;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ATest at = new ATest();
            BTest bt = new BTest();
            Test<ATest, BTest> test = new Test<ATest, BTest>(at, bt);

            Console.ReadKey();
        }
    }
}

如果我创建一个泛型类(TA和TB可以是任何东西),我如何访问每个类中的特定函数?

ATest.GetValue()返回一个int。

BTest.GetValue()返回一个字符串。

似乎某种程度上我需要将TA投射到ATest(但显然这不起作用)。

让我试着进一步解释。也许仿制药不是我的答案。

我有6个数据采集类和3个设备类的集合。在设备类中,除了DAQ类之外,代码是相同的。每个设备类都有两个DAQ类。我想把所有这些都放到一个单独的类中但是在运行时我不知道将调用哪个DAQ类。

我在想通过泛型我可以创建一个类并将两个DAQ类作为参数传递。每个设备类必须具有两个特定的DAQ类。它们不可互换。

2 个答案:

答案 0 :(得分:0)

通常,您可以使用where子句将泛型限制为特定接口:

class Test<TA, TB> where TA: IValueGetter

这样您就可以根据该界面建立合同,因此TA始终会有GetValue方法。但是,您可以通过简单的步骤:

class Test {
    public Test(IValueGetter ta, IValueGetter tb)
}

哪个更简单,不需要任何泛型。如果您希望GetValue函数返回不同类型的值并使用泛型,那么请尝试制作IGetterSetter泛型。

class Test<TA, TB> {
    public Test(IGetterSetter<string> ta, IGetterSetter<int> tb)
}

所以以你的例子为例,我会将你的仿制药降低到以下水平:

interface IGetterSetter<T> {
   void SetValue(T value);
   T GetValue();
}

class BTest : IGetterSetter<string>
class ATest : IGetterSetter<int>

答案 1 :(得分:0)

如果您需要具有公共设置器和公共getter的类型,则可以使用属性定义接口:

public interface IValueObject<T>
{
    T Value { get; set; }
}

并且非常简单地实现它:

public class StringValue : IValueObject<string>
{
     public string Value { get; set; }
}

所以,你的Test课程看起来像是:

public class Test<T1, T2>
{
    private IValueObject<T1> _value1;
    private IValueObject<T2> _value2;

    public Test(IValueObject<T1> value1, IValueObject<T2> value2)
    {
        _value1 = value1;
        _value2 = value2;
    }

    void Write()
    {
        Console.WriteLine("Value1: " + _value1.Value);
    }
}

然后您可以将其用作:

Test<string, string> test = new Test<string, string>(new StringValue(), new StringValue());