我在一个名为 Owner 的类上有一个名为 CustomerForOwner 的属性。我想要 Owner 类的只读版本,所以我创建了一个名为 OwnerReadOnly 的包装类。我遇到的问题是当我有引用类型属性时。为了创建该对象的只读版本,我使用了一个接口,以便 Owner 和 OwnerReadOnly 都可以拥有一个名为 CustomerForOwner (ICustomer) 的属性。OwnerReadOnly.CustomerForOwner 将返回 CustomerReadOnly,而 Owner.CustomerForOwner 将返回 Customer。
类的简化版本:
public class Owner : ProjectBase<Owner>, IOwner
{
private Customer _customerForOwner;
private string _ownerName
public virtual ICustomer CustomerForOwner
{
get { return _customerForOwner; }
set
{
SetField(ref _customerForOwner, value, () => CustomerForOwner);
value.PropertyChanged += this.OnItemPropertyChanged;
}
}
public virtual string OwnerName
{
get { return _ownerName; }
set { SetField(ref _ownerName, value, () => OwnerName); }
}
public Owner(DateTime created, string createdBy) :
base(created, createdBy) { }
}
public class OwnerReadOnly : Owner
{
public override ICustomer CustomerForOwner
{
get { return (CustomerReadOnly)base.CustomerForOwner; }
}
public override string OwnerName
{
get { return base.OwnerName; }
}
public OwnerReadOnly(DateTime created, string createdBy) :
base(created, createdBy)
{
throw new Exception("Object is ReadOnly, cannot create a new instance");
}
}
基类:
public abstract class ProjectBase<T> : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool _isActive;
public bool IsActive
{
get { return _isActive; }
set { SetField(ref _isActive, value,() => IsActive ); }
}
public DateTime Created { get; private set; }
public string CreatedBy { get; private set; }
public DateTime? LastUpdated { get; protected set; }
public string LastUpdatedBy { get; protected set; }
public bool IsDirty { get; protected set; }
private ProjectBase() { }
protected ProjectBase(DateTime created, string createdBy)
{
IsActive = true;
Created = created;
CreatedBy = createdBy;
LastUpdated = created;
LastUpdatedBy = createdBy;
IsDirty = false;
}
public abstract void Clone();
public abstract void Create();
public abstract void Update(DateTime lastUpdated, string lastUpdatedBy);
protected abstract void Update();
public abstract void Delete();
protected bool SetField<TField>(ref TField field, TField value, Expression<Func<TField>> selectorExpression)
{
bool returnValue = false;
if (EqualityComparer<TField>.Default.Equals(field, value))
returnValue = false;
else
{
field = value;
IsDirty = true;
OnPropertyChanged(selectorExpression);
returnValue = true;
}
return returnValue;
}
protected virtual void OnPropertyChanged<TParam>(Expression<Func<TParam>> selectorExpression)
{
MemberExpression body;
if (selectorExpression == null)
throw new ArgumentNullException("selectorExpression");
body = selectorExpression.Body as MemberExpression;
if (body == null)
throw new ArgumentException("The body must be a member expression");
OnPropertyChanged(body.Member.Name);
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
IsDirty = true;
}
protected void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
IsDirty = true;
}
我遇到的问题是使用 Owner.CustomerForOwner 属性行调用 SetField:
SetField(ref _customerForOwner, value, () => CustomerForOwner);
我收到以下编译错误:无法从用法中推断方法 'ProjectBase.SetField(ref TField, TField, System.Linq.Expressions.Expression>)' 的类型参数。尝试明确指定类型参数。
我怎样才能通过 ICustomer 作为客户?我将其更改为:
SetField(ref _customerForOwner, (Customer)value, () => CustomerForOwner);
但同样的错误。我还尝试在 Setter 的上一行将值设置为新客户,但返回了相同的编译错误。