2

基本上正如标题所说:

[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>();
}

所以,你有它......什么有效,什么无效......但问题是......为什么?显然,.NET 能够在使用DataContractandCollectionDataContract并声明类型时创建一个具体类型并格式化名称(即GenericItem<Foo>SpecialCollection<Foo>. 那么为什么不DataMember也能够格式化呢?

我可以按照上面留下的方式(ServiceContract/OperationContract排序)来理解,但我不明白的是,当你给它一个具体的类型时,操作仍然无法正常工作:

[ServiceContract(Name = "FooService")]
public interface FooService : IGenericService<Foo> { }

public interface IGenericService<T>
{
    [OperationContract(Name = "Get{0}")] //This will NOT format properly
    T Get<T>();
}

再次,为什么?显然,我在这里声明了一个具体的 Foo 类型,这意味着 IGenericService 是一个 IGenericService<Foo> 所以不应该格式化 OperationContract 名称,因为它知道类型吗?


更新:

我只记得为什么我对无法使用通用格式的 ServiceContract 感到不安......当我实现服务时,我给它一个具体的类型......

//See! I gave it a concrete type to go by!
[ServiceBehavior(...)]
public class MyService : IGenericService<Foo> { ... }

我为此创建了一个Microsoft Connect请求。如果您希望将此功能用于其他属性,请对其进行投票。http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2327048-enable-generics-for-datamemberattribute-serviceco

4

2 回答 2

1

这似乎是 MS 的实现选择。它通过System.Runtime.Serialization.DataContract以下方式建立名称:

private static XmlQualifiedName GetDCTypeStableName(Type type, DataContractAttribute dataContractAttribute)
{
  string localName;
  if (dataContractAttribute.IsNameSetExplicit)
  {
    string str = dataContractAttribute.Name;
    if (str == null || str.Length == 0)
    {
       ...
    }
    else
    {
      if (type.IsGenericType && !type.IsGenericTypeDefinition)
        str = DataContract.ExpandGenericParameters(str, type);
      localName = DataContract.EncodeLocalName(str);
    }
  }

所以它明确地构建了通用名称。对于 ServiceContract 的东西,它在System.ServiceModel.Description.TypeLoaderand中处理System.ServiceModel.Description.NamingHelper,并且对泛型类型不做任何事情(最后不是我看到的)。

所以我猜测,由于这些合同源自不同的程序集和命名空间,它们可能一开始就由不同的团队实施。

于 2011-06-28T20:23:00.070 回答
0

阅读:http: //msdn.microsoft.com/en-us/library/ms731045.aspx#Y1254

基本上,命名系统似乎最初设计时无法格式化名称,但最终 DataContract 命名系统惹恼了足够多的人(因为哈希),他们增加了格式化名称的能力。

编辑:

“但是,更改此默认名称可能是有原因的。原因之一是允许现有类型处理必须符合现有数据协定的数据。例如,存在一个名为 Person 的类型,但数据协定体现在XML 模式,要求名称为 Customer。可以通过将属性值设置为 Customer 来满足合同。

第二个原因是允许生成作为类型名称无效的名称。例如,如果数据协定要求使用不允许作为类型名称的名称,请将属性值设置为该不允许的名称。例如,字符串“$value”不允许作为类型名称,但允许作为 Name 属性值。

来源:http: //msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.name.aspx

我的猜测是,没有必要更改其他人的默认名称(包括 OperationContract、ServiceContract 等)。

于 2011-06-28T20:08:15.560 回答