Basically as the title says:
[DataContract(Name = "{0}Item")] //This will format properly
public class GenericItem<T>
{
[DataMember(Name = "The{0}")] //This will NOT format properly
public T TheItem { get; set; }
}
[CollectionDataContract(Name = "{0}Items")] //This will format properly
public SpecialCollection<T> : Collection<T> { }
[ServiceContract(Name = "{0}Service")] //This will NOT format properly
public interface IGenericService<T>
{
[OperationContract(Name = "Get{0}")] //This will NOT format properly
GenericItem<T> Get<T>();
}
So, there ya have it… what works and doesn’t work… but the question is… why? Obviously .NET is able to create a concrete type and format the name when using a DataContract and CollectionDataContract and stating the type (i.e. GenericItem<Foo> or SpecialCollection<Foo>. So why not have the DataMember also be able to format as well?
The ServiceContract/OperationContract I can sort of understand in the manner it’s left in above (sorta), but what I don’t understand is when you give it a concrete type the operations still won’t work properly:
[ServiceContract(Name = "FooService")]
public interface FooService : IGenericService<Foo> { }
public interface IGenericService<T>
{
[OperationContract(Name = "Get{0}")] //This will NOT format properly
T Get<T>();
}
Again, why? Obviously I’m declaring a concrete type of Foo here which means the IGenericService is an IGenericService<Foo> so shouldn’t the OperationContract name be formatted since it KNOWS the type?
Update:
I just remembered why I was upset about not being able to use a Generically formatted ServiceContract… when I have the implement the service I’m giving it a concrete type…
//See! I gave it a concrete type to go by!
[ServiceBehavior(...)]
public class MyService : IGenericService<Foo> { ... }
I created a Microsoft Connect request for this. Please upvote it if you want this feature for the other attributes. http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2327048-enable-generics-for-datamemberattribute-serviceco
This seems to be an implementation choice by MS.
In
System.Runtime.Serialization.DataContractit builds up the name by doing:So it explicitly builds out the generic name.
In the case of ServiceContract stuff, that is handled in
System.ServiceModel.Description.TypeLoaderandSystem.ServiceModel.Description.NamingHelper, and does not do anything with generic types (at last not that I am seeing).So I’m guessing since these contracts stem from different assemblies and namespaces, they may have been implemented by different teams to begin with.