10

Here is the constructor:

 public PartyRoleRelationship(PartyRole firstRole, PartyRole secondRole)
        {
            if (firstRole == secondRole)
                throw new Exception("PartyRoleRelationship cannot relate a single role to itself.");

            if (firstRole.OccupiedBy == null || secondRole.OccupiedBy == null)
                throw new Exception("One or both of the PartyRole parameters is not occupied by a party.");

            // Connect this relationship with the two roles.
            _FirstRole = firstRole;
            _SecondRole = secondRole;


            T = _FirstRole.GetType().MakeGenericType();

            _SecondRole.ProvisionRelationship<T>(_FirstRole); // Connect second role to this relationship.
        }

On the last line, where it calls ProvisionRelationship on _SecondRole, it's giving me the run-time error: Type or namespace 'T' could not be found...

How do I either (a) properly assign T, or (b) pass a generic type with the constructor? I've been looking through quite a few posts, but may have missed something due to a lack of understanding. Anyone's help on this would be greatly appreciated.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Phil
  • 103
  • 1
  • 1
  • 5
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Mar 03 '13 at 23:11
  • What is .ProvisionRelationship(PartyRole role) supposed to accomplish? – Moop Mar 03 '13 at 23:12

3 Answers3

14

Your class needs to be generic. So PartyRoleRelationship needs to look like this:

public class PartyRoleRelationship<T>
{
    public PartyRoleRelationship(T arg, ...)
    {
    }
}

Read more about generic classes here:

http://msdn.microsoft.com/en-us/library/sz6zd40f(v=vs.80).aspx

http://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx

Edit:

You could probably simplify you code a bit and do it like this:

public class RoleRelationship<T>
{
    public RoleRelationship(T firstRole, T secondRole)
    {
        if (firstRole.OccupiedBy == null || secondRole.OccupiedBy == null)
            throw new Exception("One or both of the Role parameters is not occupied by a party.");

        // Connect this relationship with the two roles.
        _FirstRole = firstRole;
        _SecondRole = secondRole;

        _SecondRole.ProvisionRelationship<T>(_FirstRole);
    }
}
Cheesebaron
  • 24,131
  • 15
  • 66
  • 118
  • I think you need to qualify the generic T better, otherwise you could pass in a double, string, int, object into the constructor and it would not work as expected. – Moop Mar 03 '13 at 23:49
  • Yes, that would be a very good idea. Phil, please take a look at Moop's answer as well, which shows how to specify what T actually is. – Cheesebaron Mar 03 '13 at 23:52
  • Is there a way to define T within the constructor, though, instead of passing a generic type parameter into the constructor? Like, pull the type from _SecondRole and pass that to ProvisionRelationship – Phil Mar 04 '13 at 00:02
  • Creating a generic class constructor is not possible, please see Jon Skeets answer here: http://stackoverflow.com/a/700986/368379 – Cheesebaron Mar 04 '13 at 00:13
4

Make a generic class where the generic type T is a type of the base class PartyRole:

public class PartyRoleRelationship<T> where T : PartyRole 
{
     T _FirstRole;
     T _SecondRole;

     public PartyRoleRelationship(T role1, T role2) {
         _FirstRole = role1;
         _SecondRole = role2;
         role1.ProvisionRelationship(role2)
     }

     public ProvisionRelationship(T otherRole) {
          // Do whatever you want here
     }

}
Moop
  • 3,414
  • 2
  • 23
  • 37
0

If you know the type of _FirstRole statically (is it PartyRole?), you can just use that:

_SecondRole.ProvisionRelationship<PartyRole>(_FirstRole);
user1610015
  • 6,561
  • 2
  • 15
  • 18
  • I do not. PartyRole is the base class, but it's passing derived classes of PartyRole. – Phil Mar 03 '13 at 23:03