C# 包括哪些字段?
我有一个简单的对象C# 包括哪些字段?,c#,protocol-buffers,protobuf-net,C#,Protocol Buffers,Protobuf Net,我有一个简单的对象 [ProtoContract] public class DataChangedEventArgs<T> : EventArgs { private readonly object key; private readonly T data; private readonly DataChangeType changeType; ///<summary> /// Key to identify the data
[ProtoContract]
public class DataChangedEventArgs<T> : EventArgs
{
private readonly object key;
private readonly T data;
private readonly DataChangeType changeType;
///<summary>
/// Key to identify the data item
///</summary>
public object Key
{
get { return key; }
}
[ProtoMember(2, IsRequired = true)]
public T Data
{
get { return data; }
}
[ProtoMember(3, IsRequired = true)]
public DataChangeType ChangeType
{
get { return changeType; }
}
[协议]
公共类DataChangedEventArgs:EventArgs
{
私有只读对象密钥;
私有只读数据;
私有只读数据变更类型变更类型;
///
///用于标识数据项的键
///
公共对象密钥
{
获取{return key;}
}
[原成员(2,IsRequired=true)]
公共T数据
{
获取{返回数据;}
}
[原成员(3,IsRequired=true)]
公共数据变更类型变更类型
{
获取{return changeType;}
}
我对键有一个问题。它的类型是object,但它可以是int、long或string。
我会直观地使用ProtoInclude属性来表示“expect this types”,但不幸的是,它们只是类属性。
有人知道我该如何解决这个问题吗?
作为背景,由于历史原因(以及各地的原因),公共对象密钥出现在这里,因此我非常希望避免所有重构之母;-)
有没有可能让它序列化,甚至强制它序列化为一个字符串?确实有一些技巧可以奏效;您提到的
字符串非常简单(通过使用标有[ProtoMember]
的私有属性),但我不确定您如何知道将其转换回什么类型
但是,有一种基于继承的([ProtoInclude]
)方法来处理有限的类型数(预先知道)。这里有一个例子,但我会看到我可以使它更具体地处理这种情况
对于基于字符串的方法,您可以使用前缀,例如:
public object Key {get;set;}
[ProtoMember(1)]
private object KeyString {
get {
if(Key == null) return null;
if(Key is string) return "s:"+(string)Key;
if(Key is int) return "i:"+Key.ToString();
// etc
}
set {
if(value == null) { Key = null; }
else if(value.StartsWith("s:")) {...}
// etc
}
}
好的;这里有一个例子;我强调使用固定键会比使用固定键好得多;下面的代码有点难看,但大部分代码都可以隐藏并重复使用,所以可能还不算太糟。不过,我更喜欢强类型键。我可能已经提到过;-p
using System;
using ProtoBuf;
static class Program
{
static void Main()
{
var message1 = new SomeMessageWithVariableKey<string>(123456, "abcdef");
var clone1 = Serializer.DeepClone(message1);
Console.WriteLine(clone1.Key);
Console.WriteLine(clone1.SomeOtherValue);
var message2 = new SomeMessageWithVariableKey<int>("abcdef", 123456);
var clone2 = Serializer.DeepClone(message2);
Console.WriteLine(clone2.Key);
Console.WriteLine(clone2.SomeOtherValue);
}
}
[ProtoContract]
[ProtoInclude(1, typeof(ProtoKey<int>))]
[ProtoInclude(2, typeof(ProtoKey<string>))]
abstract class ProtoKey
{
public static ProtoKey Create(object key)
{
if (key == null) return null;
if (key is string) return new ProtoKey<string> { Value = key };
if (key is int) return new ProtoKey<int> { Value = key };
throw new ArgumentException("Unexpected key type: " + key.GetType().Name);
}
public abstract object Value { get; protected set;}
public override string ToString()
{
return Convert.ToString(Value);
}
public override bool Equals(object obj)
{
ProtoKey other = obj as ProtoKey;
if (other == null) return false;
return object.Equals(Value, other.Value);
}
public override int GetHashCode()
{
object val = Value;
return val == null ? 0 : val.GetHashCode();
}
}
[ProtoContract]
sealed class ProtoKey<T> : ProtoKey
{
[ProtoMember(1)]
public T TypedValue { get; set; }
public override object Value
{
get { return TypedValue; }
protected set { TypedValue = (T)value; }
}
}
[ProtoContract]
public class SomeMessageWithVariableKey<T>
{
private SomeMessageWithVariableKey() { }
public SomeMessageWithVariableKey(object key, T someOtherValue) {
Key = key;
SomeOtherValue = someOtherValue;
}
public object Key { get; private set; }
[ProtoMember(1)]
private ProtoKey SerializationKey
{
get { return ProtoKey.Create(Key); }
set { Key = value == null ? null : value.Value; }
}
[ProtoMember(2)]
public T SomeOtherValue { get; set; }
}
使用系统;
使用ProtoBuf;
静态类程序
{
静态void Main()
{
var message1=newsomemessagewithvariablekey(123456,“abcdef”);
var clone1=Serializer.DeepClone(message1);
Console.WriteLine(克隆1.Key);
Console.WriteLine(clone1.SomeOtherValue);
var message2=newsomemessagewithvariablekey(“abcdef”,123456);
var clone2=Serializer.DeepClone(message2);
Console.WriteLine(克隆2.Key);
Console.WriteLine(clone2.SomeOtherValue);
}
}
[原始合同]
[ProtoInclude(1,typeof(ProtoKey))]
[ProtoInclude(2,typeof(ProtoKey))]
抽象类原型密钥
{
公共静态协议密钥创建(对象密钥)
{
如果(key==null)返回null;
如果(key是string)返回新的ProtoKey{Value=key};
如果(key为int)返回新的ProtoKey{Value=key};
抛出新ArgumentException(“意外的键类型:+key.GetType().Name”);
}
公共抽象对象值{get;protected set;}
公共重写字符串ToString()
{
返回Convert.ToString(值);
}
公共覆盖布尔等于(对象对象对象)
{
ProtoKey other=obj作为ProtoKey;
if(other==null)返回false;
返回object.Equals(Value,other.Value);
}
公共覆盖int GetHashCode()
{
对象值=值;
return val==null?0:val.GetHashCode();
}
}
[原始合同]
密封类ProtoKey:ProtoKey
{
[原成员(1)]
公共T类型值{get;set;}
公共覆盖对象值
{
获取{return TypedValue;}
受保护集{TypedValue=(T)值;}
}
}
[原始合同]
公共类SomeMessageWithVariableKey
{
私有SomeMessageWithVariableKey(){}
公共SomeMessageWithVariableKey(对象键,T someOtherValue){
钥匙=钥匙;
SomeOtherValue=SomeOtherValue;
}
公共对象密钥{get;private set;}
[原成员(1)]
私有协议密钥序列化密钥
{
获取{return ProtoKey.Create(Key);}
set{Key=value==null?null:value.value;}
}
[原成员(2)]
公共T SomeOtherValue{get;set;}
}