I want to have a generic print function...PrintGeneric(T)...in the following case, what am I missing?
As always your help/insight is appreciated...
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);
}
}
It doesn't compile because T could be anything, and not everything will have the myvar field.
You could make myvar a property on ITest:
public ITest
{
string myvar{get;}
}
and implement it on the classes as a property:
public class MyClass1 : ITest
{
public string myvar{ get { return "hello 1"; } }
}
and then put a generic constraint on your method:
public void PrintGeneric<T>(T test) where T : ITest
{
Console.WriteLine("Generic : " + test.myvar);
}
but in that case to be honest you are better off just passing in an ITest:
public void PrintGeneric(ITest test)
{
Console.WriteLine("Generic : " + test.myvar);
}
You're missing at least a couple of things:
Unless you're using reflection, the type arguments need to be known at compile-time, so you can't use
PrintGeneric<test2.GetType()>
... although in this case you don't need to anyway
PrintGeneric doesn't know anything about T at the moment, so the compiler can't find a member called T
Options:
Put a property in the ITest interface, and change PrintGeneric to constrain T:
public void PrintGeneric<T>(T test) where T : ITest
{
Console.WriteLine("Generic : " + test.PropertyFromInterface);
}
Put a property in the ITest interface and remove the generics entirely:
public void PrintGeneric(ITest test)
{
Console.WriteLine("Property : " + test.PropertyFromInterface);
}
Use dynamic typing instead of generics if you're using C# 4
You'll have to provide more information about the generic type T. In your current PrintGeneric method, T might as well be a string, which does not have a var member.
You may want to change var to a property rather than a field
public interface ITest
{
string var { get; }
}
And add a constraint where T: ITest to the PrintGeneric method.
In your generic method, T is just a placeholder for a type. However, the compiler doesn't per se know anything about the concrete type(s) being used runtime, so it can't assume that they will have a var member.
The usual way to circumvent this is to add a generic type constraint to your method declaration to ensure that the types used implement a specific interface (in your case, it could be ITest):
public void PrintGeneric<T>(T test) where T : ITest
Then, the members of that interface would be directly available inside the method. However, your ITest is currently empty, you need to declare common stuff there in order to enable its usage within the method.
try
public void PrintGeneric<T>(T test) where T: ITest
{
Console.WriteLine("Generic : " + test.@var);
}
as @Ash Burlaczenko has said you cant name a variable after a keyword, if you reallllly want this prefix with @ symbol to escape the keyword
You need to define something in the interface, such as:
public interface ITest
{
string Name { get; }
}
Implement ITest in your classes:
public class MyClass1 : ITest
{
public string Name { get { return "Test1"; } }
}
public class MyClass2 : ITest
{
public string Name { get { return "Test2"; } }
}
Then restrict your generic Print function, to ITest:
public void Print<T>(T test) where T : ITest
{
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With