4

Can I create a generic method that accept two types. The attributeType and ts_attributeType do not share any common parent class although they do have the same fields.

Is this possible? Or is there some way I can achieve this?

private static void FieldWriter<T>(T row)
        where T : attributeType, ts_attributeType

    {
        Console.Write(((T)row).id + "/" + (((T)row).type ?? "NULL") + "/");
    }

I have seen this answer from Jon Skeet, however I am not certain if it also applies to my question.

Some further background: Both attributeType and ts_attributeType have been created using the xsd.exe tool; and are are partial classes.

1
  • 1
    Can you make them both implement a shared interface? Commented Aug 5, 2011 at 9:16

3 Answers 3

8

No, you can't. The simplest alternative is to simply write two overloads, one for each type. You can always extract the common code if you want to avoid repeating yourself too much:

private static void FieldWriter(attributeType row)
{
    FieldWriterImpl(row.id, row.type);
}

private static void FieldWriter(ts_attributeType row)
{
    FieldWriterImpl(row.id, row.type);
}

// Adjust parameter types appropriately
private static void FieldWriterImpl(int id, string type)
{
    Console.Write(id + "/" + (type ?? "NULL") + "/");
}

Alternatively, you could use dynamic typing if you're using C# 4.

(A better solution would be to give the two classes a common interface if you possibly can - and rename them to follow .NET naming conventions at the same time :)

EDIT: Now that we've seen you can use partial classes, you don't need it to be generic at all:

private static void FieldWriter(IAttributeRow row)
{
    Console.Write(row.id + "/" + (row.type ?? "NULL") + "/");
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Jon, so is my current solution is correct a good approach?
@Ahmad: Yes, using partial classes to implement a common interface is a good solution, and one I've used elsewhere. I wouldn't call it ICommonFields though, given that it doesn't specify fields :) It also doesn't need to be generic - will edit my answer.
I missed that in my original solution. There was no need to have a generic constraint. Thanks
1

If they are partial classes, and both have the same properties, you could extract those properties into an interface and use that as your generic constraint.

public interface IAttributeType
{
   int id{get;}
   string type{get;set;}
}

Then create a partial class matching your 2 classes, and simply implement the interface:

public partial class AttributeType : IAttributeType
{
  // no need to do anything here, as long as AttributeType has id and type
}
public partial class ts_AttributeType : IAttributeType
{
  // no need to do anything here, as long as ts_AttributeType has idand type
}

Now you can constrain the generic by the interface:

private static void FieldWriter<T>(T row)
    where T : IAttributeType

{
    Console.Write(row.id + "/" + (row.type ?? "NULL") + "/");
}

1 Comment

This is especially useful when dealing with linq2sql generated classes that all return the same table data where there is no practical way to give them a common base class.
1

My current solution involves creating an interface and letting the partial classes implement it. Slightly backwards in logic.

namespace Test
{
    public partial  class attributeType: IAttributeRow {}

    public partial class ts_attributeType : IAttributeRow {}

    public interface ICommonFields
    {
        string id { get; set; }
        string type { get; set; }
    }
}


    private static void FieldInfo<T>(T row)
        where T : IAttributeRow 

    {
        Console.Write(((T)row).id + "/" + (((T)row).type ?? "NULL") + "/");
    }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.