【问题标题】:Implement interface and use code from existing implementation of the interface实现接口并使用接口现有实现中的代码
【发布时间】:2013-08-28 12:28:56
【问题描述】:

我正在尝试实现ITableEntity 接口,以便可以在其上添加[DataContract] 属性。但是如果我自己实现这个接口,我就必须给ReadEntityWriteEntity 方法一个body。

但是有一个类已经实现了ITableEntity 接口,并给ReadEntityWriteEntity 方法提供了一个主体,即TableEntity.cs

如何让我的接口实现使用TableEntity 类中的方法?

[编辑]

[DataContract]
public class SerializableTableEntity : ITableEntity 
{
    private TableEntity tableEntity;

    public string ETag { get; set; }
    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public DateTimeOffset Timestamp { get; set; }

    public SerializableTableEntity()
    {
        tableEntity = new TableEntity();
    }

    public void ReadEntity(IDictionary<string, EntityProperty> properties, Microsoft.WindowsAzure.Storage.OperationContext operationContext)
    {
        tableEntity.ReadEntity(properties, operationContext);
    }

    public IDictionary<string, EntityProperty> WriteEntity(Microsoft.WindowsAzure.Storage.OperationContext operationContext)
    {
        return tableEntity.WriteEntity(operationContext);
    }
}

【问题讨论】:

  • 也许我不明白你的问题,但你想从类TableEntity 派生,即让那个类成为你类的基类吗?因为如果这样做,您将“免费”继承方法和接口。
  • 嗨,这就是我最初所做的,但我需要能够序列化 TableEntity 类,并且 TableEntity 类没有在类上装饰的 [DataContract] 属性。所以我坚持创建自己的实现。

标签: c# azure interface


【解决方案1】:

存储表中的每个属性都是空白的原因是因为 WriteEntity 和 ReadEntity 使用空白对象来存储和写入数据。

您将对象的序列化委托给“tableEntity”,但您的任何属性都不存在。

建议:您需要在派生自 TableEntity 的类中实现所有 SerializableTableEntity 的属性,在 SerializableTableEntity 实体中包含该类型的变量,并将每个成员的属性从 SerializableTableEntity 获取/设置委托给这个新对象。

这有意义吗?

编辑:按要求编写代码示例(尽管您不会喜欢它)

    [DataContract]
public class SerializableTableEntity : ITableEntity
{
    private CustomEntity tableEntity;

    public string ETag { 
    {
        get
        {
            return tableEntity.ETag;
        }
        set
        {
            tableEntity.Etag = value;
        }
    }

    public string PartitionKey
    {
        get
        {
            return tableEntity.PartitionKey;
        }
        set
        {
            tableEntity.PartitionKey = value;
        }
    }

    public string RowKey
    {
        get
        {
            return tableEntity.RowKey;
        }
        set
        {
            tableEntity.RowKey = value;
        }
    }

    public DateTimeOffset Timestamp
    {
        get
        {
            return tableEntity.Timestamp;
        }
        set
        {
            tableEntity.Timestamp = value;
        }
    }

    public string PropertyOne
    {
        get
        {
            return tableEntity.PropertyOne;
        }
        set
        {
            tableEntity.PropertyOne = value;
        }
    }


    public SerializableTableEntity()
    {
        tableEntity = new CustomEntity();
    }

    public void ReadEntity(IDictionary<string, EntityProperty> properties, Microsoft.WindowsAzure.Storage.OperationContext operationContext)
    {
        tableEntity.ReadEntity(properties, operationContext);
    }

    public IDictionary<string, EntityProperty> WriteEntity(Microsoft.WindowsAzure.Storage.OperationContext operationContext)
    {
        return tableEntity.WriteEntity(operationContext);
    }
}

public class CustomEntity : TableEntity
{
    public string PropertyOne { get; set; }
}

【讨论】:

  • 是的,这是有道理的。但我没有完全理解你的建议是什么意思。你是说我要存储在表中的所有对象,都必须添加到SerializableTableEntity 类中?
  • Igorek,如果你有时间,一个小的代码示例会很好。
  • 抱歉,在开会,提供了代码示例,虽然我怀疑你会喜欢它
  • 没问题,您的方法也不起作用,因为CustomEntity 继承自TableEntity。所以它不会将CustomEntity 序列化为字节数组。
【解决方案2】:

我最终创建了这些类的精确副本并将它们设为Serializable。但是能够进行一些复杂的查询似乎也是一个挑战。所以我们搬到了SQL数据库。

【讨论】:

    【解决方案3】:

    要么委托“无趣”的方法(更现实的例子是here):

    class YourClass : Interface {
        public void ReadEntity()
        {
           delegateTo.ReadEntity();
        }
        TableEntity delegateTo = new TableEntity();
    }
    

    或者只是在它们内部抛出一个异常(比如NotImplementedException)——后者只有在没有调用这些方法时才对你有效。

    【讨论】:

    • 嗨,这是我的第一种方法,这种方法的问题是天蓝色表只填充了标准属性,如 partitionKey、rowKey 和 DateTimeStamp。我自己的属性没有保存在表中。如果我只使用 TableEntity 它可以工作。因此,“错误”所在的不是我自己的属性。
    【解决方案4】:

    您可以创建一个包含 TableEntity 类的实现的类,还可以添加您想要的功能。这类似于Decorator Pattern

    [Attributes...]
    public class MyTableEntity : ITableEntity {
      private TableEntity decoratedTableEntity;
    
      public void ReadEntity(args...) {
        decoratedTableEntity.ReadEntity(args...);
      }
    
    }
    

    要使解决方案更通用,请将 decoratedTableEntity 更改为 ITableEntity。

    【讨论】:

    • 嗨,这个方法和我对尖牙说的一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    • 2016-06-20
    • 2020-12-03
    相关资源
    最近更新 更多