Reputation: 2077
Would the following code work in c#?
public class Foo
{
public string Name { get; set; }
}
public class Related_Foo
{
public string Name { get; set; }
}
class Program
{
static void do_something<T>(T t)
{
string n = t.Name;
}
static void Main(string[] args)
{
Foo f = new Foo();
do_something(f);
}
}
In .Net 4 the compiler is complaining:
'T' does not contain a definition for 'Name' and no extension method 'Name' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?)
Upvotes: 0
Views: 92
Reputation: 520
If do_something should always take Foo or anything derived from Foo (rather than just always have a Property called Name), you could do this:
static void do_something<T>(T t) where T : Foo
{
string n = t.Name;
}
This is constraining the Type passed in to be of Type Foo or any types derived from it.
Upvotes: 0
Reputation: 14312
You need to put a constrain on the generic type T
- otherwise how should compiler know about it?
Make an Ifoo
and then
do_something<T>(T t) where T : IFoo
interface IFoo
{
string Name {get;set;}
}
Upvotes: 3
Reputation: 6116
No, this code will not work in C#, because there is nothing that constraints the type T
to have a property called Name
. Templates in C# does not work the same way as in C++, where the compiler can expand them at compile time and verify that certain members that are used actually exists.
To make it work you could add a constraint that T
must be of a type that has a property called name. For example create an interface:
public interface IFoo
{
string Name { get; }
}
and have your classes implement this interface.
Then add the constraint to your method as follows:
static void do_something<T>(T t) where T : IFoo
{
string n = t.Name;
}
If all your classes have a common base class that has a property Name
, such as if Related_Foo
was derived from Foo
you could constrain it to the class type instead, same syntax:
static void do_something<T>(T t) where T : Foo
{
string n = t.Name;
}
Upvotes: 0