chhenning
chhenning

Reputation: 2077

Passing a generic class into function at compile time

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

Answers (3)

Tory
Tory

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

NSGaga
NSGaga

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

DeCaf
DeCaf

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

Related Questions