我想要一个通用的打印功能... PrintGeneric(T)......在下面的例子中,我缺少什么?
一如既往,感谢您的帮助/见解......
public interface ITest
{}
public class MyClass1 : ITest
{
public string myvar = "hello 1";
}
public class MyClass2 : ITest
{
public string myvar = "hello 2";
}
class DoSomethingClass
{
static void Main()
{
MyClass1 test1 = new MyClass1();
MyClass2 test2 = new MyClass2();
Console.WriteLine(test1.myvar);
Console.WriteLine(test2.myvar);
Console.WriteLine(test1.GetType());
PrintGeneric(test1);
PrintGeneric<test2.GetType()>(test2);
}
// following doesn't compile
public void PrintGeneric<T>(T test)
{
Console.WriteLine("Generic : " + test.myvar);
}
}
答案 0 :(得分:24)
它没有编译,因为T可以是任何东西,而不是所有东西都有myvar
字段。
您可以myvar
上的ITest
属性:
public ITest
{
string myvar{get;}
}
并在类上实现它作为属性:
public class MyClass1 : ITest
{
public string myvar{ get { return "hello 1"; } }
}
然后对您的方法设置一个通用约束:
public void PrintGeneric<T>(T test) where T : ITest
{
Console.WriteLine("Generic : " + test.myvar);
}
但在这种情况下,说实话,你最好只是传递一个ITest:
public void PrintGeneric(ITest test)
{
Console.WriteLine("Generic : " + test.myvar);
}
答案 1 :(得分:6)
你至少缺少一些东西:
除非您使用反射,否则需要在编译时知道类型参数,因此您无法使用
PrintGeneric<test2.GetType()>
......虽然在这种情况下你无论如何都不需要
PrintGeneric
目前对T
一无所知,因此编译器无法找到名为T
的成员
选项:
在ITest
界面中添加一个媒体资源,然后将PrintGeneric
更改为约束T
:
public void PrintGeneric<T>(T test) where T : ITest
{
Console.WriteLine("Generic : " + test.PropertyFromInterface);
}
在ITest
界面中放置一个属性并完全删除泛型:
public void PrintGeneric(ITest test)
{
Console.WriteLine("Property : " + test.PropertyFromInterface);
}
如果您使用的是C#4,请使用动态类型代替泛型
答案 2 :(得分:2)
在通用方法中,T
只是一个类型的占位符。但是,编译器本身并不了解运行时使用的具体类型,因此不能假定它们将具有var
成员。
规避这种情况的常用方法是在方法声明中添加泛型类型约束,以确保使用的类型实现特定的接口(在您的情况下,它可以是ITest
):
public void PrintGeneric<T>(T test) where T : ITest
然后,该接口的成员将直接在该方法中可用。但是,您的ITest
目前为空,您需要在那里声明常用内容,以便在方法中使用它。
答案 3 :(得分:2)
您必须提供有关通用类型T
的更多信息。在您当前的PrintGeneric
方法中,T
也可能是string
,其中没有var
成员。
您可能希望将var
更改为属性而非字段
public interface ITest
{
string var { get; }
}
并向where T: ITest
方法添加约束PrintGeneric
。
答案 4 :(得分:1)
您需要在界面中定义一些内容,例如:
public interface ITest
{
string Name { get; }
}
在您的课程中实施ITest
:
public class MyClass1 : ITest
{
public string Name { get { return "Test1"; } }
}
public class MyClass2 : ITest
{
public string Name { get { return "Test2"; } }
}
然后将您的通用Print
功能限制为ITest
:
public void Print<T>(T test) where T : ITest
{
}
答案 5 :(得分:0)
试
public void PrintGeneric<T>(T test) where T: ITest
{
Console.WriteLine("Generic : " + test.@var);
}
正如@Ash Burlaczenko所说,你不能在一个关键字之后命名一个变量,如果你真的希望这个带有@符号的前缀来转义关键字
答案 6 :(得分:0)
您无法使用通用。{/ p>访问var
尝试类似
的内容Console.WriteLine("Generic : {0}", test);
并覆盖ToString
方法[1]
[1] http://msdn.microsoft.com/en-us/library/system.object.tostring.aspx