How to prevent property setter from modifying private property data - c#

Let me explain my question by posing a hypothetical situation. Lets start with a class:
public class PaymentDetails
{
public int Id {get;set;}
public string Status {get;set;}
}
And then I have another class:
public class PaymentHelper
{
private PaymentDetails _paymentDetails;
public PaymentDetails MyPaymentDetails{ get { return _paymentDetails; } }
public PaymentHelper()
{
_paymentDetails = new PaymentDetails();
}
public void ModifyPaymentDetails(string someString)
{
// code to take the arguments and modify this._paymentDetails
}
}
OK, so I have these two classes. PaymentHelper has made the property MyPaymentDetails read-only.
So I cannot instantiate PaymentHelper and modify MyPaymentDetails like this:
PaymentHelper ph = new PaymentHelper();
ph.MyPaymentDetails = new PaymentDetails(); // Not allowed!!!
But I can modify the public properties inside of ph.MyPaymentDetails like this:
ph.MyPaymentDetails.Status = "Some status"; // This is allowed
How do I prevent that from working? Or is there no good way of doing that?

A property may apply access modifiers to individual accessors, for instance:
public string Status { get; private set; }
The scope of access is left to your circumstance. Keeping it private, I'm sure you can tell, will mean only elements within the scope of the current class can use the setter, protected would allow inheritors to use it, etc.
Obviously your classes need to be engineered properly from the bottom up, so as to account for appropriate scoping and robust management when used further up the hierarchy.

The idea of protecting the properties of a complex type that is itself a property isn't available from a language construct at that level.
One option is to design the contained type in such a way as to make its properties read-only using the access modifiers (public set, protected set, private set, etc).
My preference is to expose it as an interface to public consumers:
public class PaymentHelper
{
private PaymentDetails _paymentDetails;
public IPaymentDetails MyPaymentDetails{ get { return _paymentDetails; } }
public PaymentHelper()
{
_paymentDetails = new PaymentDetails();
}
public void ModifyPaymentDetails(string someString)
{
// code to take the arguments and modify this._paymentDetails
}
}
interface IPaymentDetails
{
int Status { get; }
}
Code inside the PaymentHelper class can then use the PaymentDetails class directly, and code outside the class won't be able to use PaymentDetails unless they cast directly to it, which you can stop if you don't release the PaymentDetails class and only provide the interface.
Of course, you can never really stop the determined person who may use reflection to set things. I tend to let these people break the code :-)

Another solution is not to expose the PaymentDetails object directly, but rather wrap the properties you wish to expose. For example:
public class PaymentHelper
{
private PaymentDetails _paymentDetails;
public string PaymentDetailsStatus { get { return _paymentDetails.Status; } }
public PaymentHelper()
{
_paymentDetails = new PaymentDetails();
}
public void ModifyPaymentDetails(string someString)
{
// code to take the arguments and modify this._paymentDetails
}
}

Edit: You could always let the behavior of value types take care of this for you. Change PaymentDetails to a struct instead of a class:
public struct PaymentDetails
{
public int Id { get; set; }
public string Status { get; set; }
}
public class PaymentHelper
{
public PaymentDetails Details { get; set; }
}
If you then try to
ph.Details.Status = "Some status"; //
You'll get a compiler error telling you that you can't do this. Since value types are returned, well, by value, you can't modify the .Status property.
Or...
If PaymentDetails and PaymentHelper are declared in the same class library (separate from the code you want to prevent from writing to the .MyPaymentDetails property, you could use:
public class PaymentDetails
{
public int Id { get; internal set; }
public string Status { get; internal set; }
}
public class PaymentHelper
{
public PaymentDetails Details { get; private set; }
}
which will prevent anything declared outside of that class library from writing to .Id or .Status.
Or, force access to .Id and .Status to go through the helper class instead of allowing read access to a .Details property:
public class PaymentHelper
{
private PaymentDetails _details;
public string Id { get { return _details.Id; } private set { _details.Id=value; } }
public string Status { get { return _details.Status; } private set { _details.Status = value; } }
}
Of course, if you're going to do that, you could just
public calss PaymentDetails
{
public int Id { get; protected set; }
public string Status { get; protected set; }
}
public class PaymentHelper : PaymentDetails
{
}
... assuming that this sort of inheritance fits with the rest of your architecture.
Or, just to illustrate the interface suggestion proposed by #MrDisappointment
public interface IDetails
{
int Id { get; }
string Status { get; }
}
public class PaymentDetails : IDetails
{
public int Id { get; private set; }
public string Status { get; private set; }
}
public class PaymentHelper
{
private PaymentDetails _details;
public IDetails Details { get { return _details; } private set { _details = value; } }
}

So there are two ways that I can think of to deal with this. One is really simple:
public class PaymentDetails
{
private int _id;
private bool _idSet = false;
int Id
{
get
{
return _id;
}
set
{
if (_idSet == false)
{
_id = value;
_idSet == true;
}
else
{
throw new ArgumentException("Cannot change an already set value.");
}
}
}
private string _status;
private bool _statusSet = false;
string Status
{
get
{
return _status;
}
set
{
if (_statusSet == false)
{
_status = value;
_statusSet = true;
}
else
{
throw new ArgumentException("Cannot change an already set value.");
}
}
}
The simple solution only allows values to be set once. Changing anything requires creating a new instance of the class.
The other is rather complex but very versatile:
public interface IPaymentDetails : IEquatable<IPaymentDetails>
{
int Id { get; }
string Status { get; }
}
public class PaymentDetails : IPaymentDetails, IEquatable<IPaymentDetails>
{
public PaymentDetails()
{
}
public PaymentDetails(IPaymentDetails paymentDetails)
{
Id = paymentDetails.Id;
Status = paymentDetails.Status;
}
public static implicit operator PaymentDetails(PaymentDetailsRO paymentDetailsRO)
{
PaymentDetails paymentDetails = new PaymentDetails(paymentDetailsRO);
return paymentDetails;
}
public override int GetHashCode()
{
return Id.GetHashCode() ^ Status.GetHashCode();
}
public bool Equals(IPaymentDetails other)
{
if (other == null)
{
return false;
}
if (this.Id == other.Id && this.Status == other.Status)
{
return true;
}
else
{
return false;
}
}
public override bool Equals(Object obj)
{
if (obj == null)
{
return base.Equals(obj);
}
IPaymentDetails iPaymentDetailsobj = obj as IPaymentDetails;
if (iPaymentDetailsobj == null)
{
return false;
}
else
{
return Equals(iPaymentDetailsobj);
}
}
public static bool operator == (PaymentDetails paymentDetails1, PaymentDetails paymentDetails2)
{
if ((object)paymentDetails1 == null || ((object)paymentDetails2) == null)
{
return Object.Equals(paymentDetails1, paymentDetails2);
}
return paymentDetails1.Equals(paymentDetails2);
}
public static bool operator != (PaymentDetails paymentDetails1, PaymentDetails paymentDetails2)
{
if (paymentDetails1 == null || paymentDetails2 == null)
{
return ! Object.Equals(paymentDetails1, paymentDetails2);
}
return ! (paymentDetails1.Equals(paymentDetails2));
}
public int Id { get; set; }
public string Status { get; set; }
}
public class PaymentDetailsRO : IPaymentDetails, IEquatable<IPaymentDetails>
{
public PaymentDetailsRO()
{
}
public PaymentDetailsRO(IPaymentDetails paymentDetails)
{
Id = paymentDetails.Id;
Status = paymentDetails.Status;
}
public static implicit operator PaymentDetailsRO(PaymentDetails paymentDetails)
{
PaymentDetailsRO paymentDetailsRO = new PaymentDetailsRO(paymentDetails);
return paymentDetailsRO;
}
public override int GetHashCode()
{
return Id.GetHashCode() ^ Status.GetHashCode();
}
public bool Equals(IPaymentDetails other)
{
if (other == null)
{
return false;
}
if (this.Id == other.Id && this.Status == other.Status)
{
return true;
}
else
{
return false;
}
}
public override bool Equals(Object obj)
{
if (obj == null)
{
return base.Equals(obj);
}
IPaymentDetails iPaymentDetailsobj = obj as IPaymentDetails;
if (iPaymentDetailsobj == null)
{
return false;
}
else
{
return Equals(iPaymentDetailsobj);
}
}
public static bool operator == (PaymentDetailsRO paymentDetailsRO1, PaymentDetailsRO paymentDetailsRO2)
{
if ((object)paymentDetailsRO1 == null || ((object)paymentDetailsRO2) == null)
{
return Object.Equals(paymentDetailsRO1, paymentDetailsRO2);
}
return paymentDetailsRO1.Equals(paymentDetailsRO2);
}
public static bool operator != (PaymentDetailsRO paymentDetailsRO1, PaymentDetailsRO paymentDetailsRO2)
{
if (paymentDetailsRO1 == null || paymentDetailsRO2 == null)
{
return ! Object.Equals(paymentDetailsRO1, paymentDetailsRO2);
}
return ! (paymentDetailsRO1.Equals(paymentDetailsRO2));
}
public int Id { get; private set; }
public string Status { get; private set;}
}
public class PaymentHelper
{
private PaymentDetails _paymentDetails;
public PaymentDetailsRO MyPaymentDetails
{
get
{
return _paymentDetails;
}
}
public PaymentHelper()
{
_paymentDetails = new PaymentDetails();
}
public void ModifyPaymentDetails(string someString)
{
// code to take the arguments and modify this._paymentDetails
}
}
The complex solution allows a changeable backing store, but presents a readonly version to the consumer that cannot be changed by outsiders to your helper class.
Note that both patterns only work if you implement them all the way down the object graph or stick to value types and strings.

You can't prevent that, the property returns a refrence to a PaymentDetails, and once somebody has that, it is out of your control.
However, you can just wrap the PaymentDetails. Instead of returning it verbatim, offer only getters for its public properties.
You can also assign access modifiers for the PaymentDetails class like so:
public string Status { get; private set; }
if you don't need the class elsewhere with a public setter.

Yet another solution: Make setters internal
This is the pragmatical way if the PaymentHelper is in the same assembly of PaymentDetails and the clients of PaymentHelper are in another assembly.

Yet another solution: Delegate from PaymentHelper to PaymentDetails.
This is to add the same properties to PaymentHelper as in PaymentDetails.
If you have many properties you can let generate the delegating properties into PaymentHelper by ReSharper. Place cursor on *_paymentDetails* of line
private PaymentDetails _paymentDetails;
Press Alt+Insert->Delegating Members. Then all PaymentHelper properties delegate to PaymentDetails properties.

Related

Is there a name for this creation pattern?

What should I be calling the "BFactory" below. Its not really a Factory since there is no selection of a concrete class happening, and its not necessarily creating an object each time. Its kind of a Pool but the users do not return the Bs they get to the pool after they are done with them. It could be called a Cache but performance is not the primary intention. The intention is that everyone who is using the same BFactory will get the same B when they pass the same A which starts to sound kind of like a singleton-ish.
public class A
{
public int MyProperty { get; set; }
}
public class B
{
public B(A wrapped)
{
Wrapped = wrapped;
}
public A Wrapped { get; set; }
}
public class BFactory
{
private Dictionary<A,B> _created = new Dictionary<A,B>();
public B GetB(A a)
{
if (_created.ContainsKey(a) == false)
{
_created[a] = new B(a);
}
return _created[a];
}
}
here is a slightly more real example:
The value from MyModel is shown in several locations in the app by binding a TextBlock to the ValueString property of MyViewModel. The user can select to present the value as a percent or a decimal and it should be updated in all locations if it is updated in one.
public class MyModel
{
public int Value { get; set; }
}
public class MyViewModel
{
private readonly MyModel _model;
public MyViewModel(MyModel model)
{
_model = model;
}
public string ValueString
{
get { return string.Format(FormatString, _model.Value); }
}
public string FormatString { get; set; }
}
public class MyViewModelFactory
{
private readonly Dictionary<MyModel, MyViewModel> _created = new Dictionary<MyModel, MyViewModel>();
public MyViewModel GetViewModel(MyModel model)
{
if (_created.ContainsKey(model) == false)
{
_created[model] = new MyViewModel(model);
}
return _created[model];
}
}

Categorizing class functions in groups

Imagine a class as follows.. It's a class provided to me to work with.. I cannot change its source..
public class MyClass
{
object _Object { get; set; }
public void FuncA1() { _Object = new object(); }
public void FuncA2() { _Object = new List<object>(); }
public int FuncB1() { _Object = 0; return 0; }
public int FuncB2() { _Object = 123; return 123; }
public string FuncC1() { _Object = null; return null; }
public string FuncC2() { _Object = "Hello"; return "Hello"; }
}
Im trying to create a wrapper for this class, such that I can group its many functions into categories..
MyWrapper.Voids.FuncA1();
MyWrapper.Voids.FuncA2();
MyWrapper.Integers.FuncB1();
MyWrapper.Integers.FuncB2();
MyWrapper.Strings.FuncC1();
MyWrapper.Strings.FuncC2();
The only solution I can think of for this scenario is to design the wrapper like this:
public class MyWrapper
{
MyClass _Instance { get; set; }
public _Void Voids { get; private set; }
public _Integer Integers { get; private set; }
public _String Strings { get; private set; }
public class _Void
{
MyWrapper _Parent { get; set; }
public void FuncA1() { _Parent._Instance.FuncA1(); }
public int FuncA2() { return _Parent._Instance.FuncA2(); }
}
public class _Integer
{
...
}
public class _String
{
...
}
public MyWrapper()
{
_Instance = new MyClass();
Voids = new _Voids(this);
Integers = new _Integer(this);
Strings = new _String(this);
}
}
This solution works, but has a number of problems:
- The inner classes are forced to be public, which allows them to be instantiated by the user..
- I am forced to maintain a reference of the parent object in the child classes..
Is there a better way of doing this?
EDIT: The code posted initially was a bit confusing, in the sense that it was diverting attention away from the core issue and more into the issues of whether a function would cause exceptions or not if they all work on the same object..
NOTE: This is not actual code.. I hacked together this example to show what I'm trying to do.. CREATE A WRAPPER AROUND AN OBJECT (I cannot change the original object's code) AND GROUP FUNCTIONS INTO CATEGORIES..
FINAL EDIT: following suggestion by Juharr.. here's what ive done to accomplish what i wanted.. for the betterment of others..
public interface IVoid
{
void FuncA1();
void FuncA2();
}
public interface IInteger
{
int FuncB1();
int FuncB2();
}
public class MyWrapper
{
public MyClass Instance { get; private set; }
public IVoid Voids { get; private set; }
public IInteger Integers { get; private set; }
private abstract class MyBase
{
protected MyWrapper Parent { get; set; }
protected MyClass Instance { get { return Parent.Instance; } }
public MyBase(MyWrapper oParent) { Parent = oParent; }
}
private class MyVoid : MyBase, IVoid
{
public MyVoids (MyWrapper oParent) : base(oParent) { }
public void FuncA1() { Instance.FuncA1(); }
public void FuncA2() { Instance.FuncA2(); }
}
private class MyInteger : MyBase, IInteger
{
public MyInteger (MyWrapper oParent) : base(oParent) { }
public int FuncB1() { return Instance.FuncB1(); }
public int FuncB2() { return Instance.FuncB2(); }
}
public MyWrapper()
{
Instance = new MyClass();
Voids = new MyVoid(this);
Integers = new MyInteger(this);
}
}
You could write public interfaces instead. Then your inner classes don't have to be public. So something like this.
public interface IIntger
{
void Set(int iValue);
int Get();
}
public class MyWrapper
{
MyClass _Instance { get; set; }
public IInteger Integer { get; private set; }
private class _Integer : IInteger
{
MyWrapper _Parent { get; set; }
public void Set(int iValue) { _Parent._Instance.IntegerSet(iValue); }
public int Get() { return _Parent._Instance.IntegerGet(); }
}
public MyWrapper()
{
_Instance = new MyClass();
Integer = new _Integer(this);
}
}
EDIT:
To answer the second part of your question you will either need the reference to the parent class or a reference to the class you are wrapping. So you could have this instead.
public class MyWrapper
{
public IInteger Integer { get; private set; }
private class _Integer : IInteger
{
MyClass _Instance { get; set; }
public _Integer(MyClass myClass) { _Instance = myClass; }
public void Set(int iValue) { _Instance.IntegerSet(iValue); }
public int Get() { return _Instance.IntegerGet(); }
}
public MyWrapper(MyClass instance)
{
Integer = new _Integer(instance);
}
}

help me to choose between two designs

// stupid title, but I could not think anything smarter
I have a code (see below, sorry for long code but it's very-very simple):
namespace Option1
{
class AuxClass1
{
string _field1;
public string Field1
{
get
{
return _field1;
}
set
{
_field1 = value;
}
}
// another fields. maybe many fields maybe several properties
public void Method1()
{
// some action
}
public void Method2()
{
// some action 2
}
}
class MainClass
{
AuxClass1 _auxClass;
public AuxClass1 AuxClass
{
get
{
return _auxClass;
}
set
{
_auxClass = value;
}
}
public MainClass()
{
_auxClass = new AuxClass1();
}
}
}
namespace Option2
{
class AuxClass1
{
string _field1;
public string Field1
{
get
{
return _field1;
}
set
{
_field1 = value;
}
}
// another fields. maybe many fields maybe several properties
public void Method1()
{
// some action
}
public void Method2()
{
// some action 2
}
}
class MainClass
{
AuxClass1 _auxClass;
public string Field1
{
get
{
return _auxClass.Field1;
}
set
{
_auxClass.Field1 = value;
}
}
public void Method1()
{
_auxClass.Method1();
}
public void Method2()
{
_auxClass.Method2();
}
public MainClass()
{
_auxClass = new AuxClass1();
}
}
}
class Program
{
static void Main(string[] args)
{
// Option1
Option1.MainClass mainClass1 = new Option1.MainClass();
mainClass1.AuxClass.Field1 = "string1";
mainClass1.AuxClass.Method1();
mainClass1.AuxClass.Method2();
// Option2
Option2.MainClass mainClass2 = new Option2.MainClass();
mainClass2.Field1 = "string2";
mainClass2.Method1();
mainClass2.Method2();
Console.ReadKey();
}
}
What option (option1 or option2) do you prefer ? In which cases should I use option1 or option2 ? Is there any special name for option1 or option2 (composition, aggregation) ?
According to Law of Demeter, Option2. That way you can freely change the implementation of MainClass, You don't have to worry about calling code relying on details of AuxClass1, and indeed can remove it entirely if needed.
EDIT
interface IAuxClass1
{
string Field1 { get; set; }
void Method1();
void Method2();
}
class AuxClass1 : IAuxClass1
{
string _field1;
public string Field1
{
get
{
return _field1;
}
set
{
_field1 = value;
}
}
// another fields. maybe many fields maybe several properties
public void Method1()
{
// some action
}
public void Method2()
{
// some action 2
}
}
public class MyClass : ServiceContainer
{
public MyClass()
{
this.AddService(typeof(IAuxClass1), new AuxClass1());
}
public MyClass(IAuxClass1 auxClassInstance)
{
this.AddService(typeof(IAuxClass1), auxClassInstance);
}
public IAuxClass1 AuxClass
{
get
{
return (this.GetService(typeof(IAuxClass1)) as IAuxClass1);
}
}
}
Original
I tihnk MainClass should derive from AuxClass..
class MainClass : AuxClass1
{
}
I would start with implementing a nice feature of C# called "automatic properties". Instead of writing
private ThisType _myThing;
public ThisType MyThing
{
get { return _myThing; }
set { _myThing = value; }
}
you can write
public ThisType MyThing { get; set; }
and the compiler will generate the exact same IL. On top of this, you can add some options, for example making the setter private:
public ThisType MyThing { get; private set; }
In your case, I would go for option 3:
namespace Option3
{
public AuxClass
{
public string Field1 { get; set; }
public Method1() { ... }
public Method1() { ... }
}
public MainClass
{
public AuxClass Aux { get; private set; }
public MainClass(AuxClass aux)
{
this.Aux = aux;
}
}
}
class Program
{
static void Main(string[] args)
{
Option3.AuxClass = auxClass3 = new Option3.AuxClass();
Option3.MainClass mainClass3 = new Option3.MainClass(auxClass3);
mainClass3.Aux.Field1 = "string2";
mainClass3.Aux.Method1();
mainClass3.Aux.Method2();
}
}
This way, you lock the AuxClass reference once it's set (like in Option 2) while not locking up yourself for changes in the AuxClass interface (like in Option 1).
Decision of choosing design is based on different factors,
Shorter code => Option 1
Monitor activity of each functionality and every access => Option 2, however using linq and expressions, you can write a generalized code that can work with even option 1, but thats too complicated to discuss here.

NHibernate and State Pattern persistance - a good implementation?

Below is my implementation of the state pattern. In order to persist the State object to my database with NHibernate, I am assigning each state class an enum value. This is stored as a private field on the entity, and mapped to a integer field in my database table.
I want to know whether this is a good implementation as I will be using the state pattern throughout my application and want to get it right the first time. Thanks
public class Order
{
private OrderStatusEnum _statusId;
public virtual Guid Id { get; set; }
private OrderState _status;
public virtual OrderState Status {
get
{
if (_status == null)
_status = GetState(_statusId);
return _status;
}
set
{
_status = value;
_statusId = _status.Id;
}
}
private OrderState GetState(OrderStatusEnum status)
{
switch (_statusId) {
case OrderStatusEnum.Pending:
return new Submitted(this);
case OrderStatusEnum.Completed:
return new Completed(this);
default:
return new NewOrder(this);
}
}
}
public abstract class OrderState
{
private readonly Order _order;
public OrderState(Order order) {
_order = order;
}
internal Order Order { get { return _order; } }
public abstract OrderStatusEnum Id { get; }
public virtual void Submit() {
throw new InvalidOperationException(
string.Format("Can't Submit a {0} Order", this.GetType().Name)
);
}
public virtual void Complete() {
throw new InvalidOperationException(
string.Format(string.Format("Can't Cancel a {0} Order", this.GetType().Name))
);
}
protected internal void _Submit() {
Order.Status = new Submitted(Order);
}
protected internal void _Complete() {
Order.Status = new Completed(Order);
}
}
public class NewOrder : OrderState
{
public NewOrder(Order order) : base(order) { }
public override OrderStatusEnum Id {
get { return OrderStatusEnum.New; }
}
public override void Submit() {
_Submit();
}
}
public class Submitted : OrderState
{
public Submitted(Order order) : base(order) { }
public override OrderStatusEnum Id {
get { return OrderStatusEnum.Pending; }
}
public override void Complete() {
_Complete();
}
}
public class Completed : OrderState
{
public Completed(Order order) : base(order) { }
public override OrderStatusEnum Id {
get { return OrderStatusEnum.Completed; }
}
}
public enum OrderStatusEnum {
New = 1,
Pending = 2,
Completed = 3
}
Not sure whether to answer or add a comment, but your approach worked very well for me in a similar situation.
I also experimented with the approach described here using the Tarantino framework, but I found it easier to extend from your code.

Comparing 2 NHibernate loaded object problem

I have a class Client like that:
public class Client
{
public Person Pers { get; set; }
}
And I have 2 Person´s child class :
public class PersonType1 : Person {...}
public class PersonType2 : Person {...}
So, my Client could be PersonType1 or PersonType2...
I load 2 Client using NHibernate... And after that, I´m trying to compare than (the difference are on PersonType1 and PersonType2 attributes)...
I tried that:
public class ClientComparer : IComparer<Client>
{
public int Compare(Client __c1, Client __c2)
{
string _name1 = __c1.Person.GetType().Equals(typeof(PersonType2)) ? ((PersonType2)(__c1.Person)).Type2Att : ((PersonType1)(__c1.Person)).Type1Att ;
string _name2 = __c2.Person.GetType().Equals(typeof(PersonType2)) ? ((PersonType2)(__c2.Person)).Type2Att : ((PersonType1)(__c2.Person)).Type1Att;
if (_name1 == null)
{
if (_name2 == null)
{
return 0;
}
return -1;
}
if (_name2 == null)
{
return 1;
}
return _name1.CompareTo(_name2);
}
}
The problem is that __c1.Person.GetType() returs PersonProxy127b2a2f44f446089b336892a673643b instead of the correct type... It´s because of NHibernate...
How can I do that ? Ideas?
Thanks
Rather than having two different attributes on PersonType1 and PersonType2, define a single property in the base class Person and override it in each of the child classes. Using polymorphic behavior rather than explicit type-checking is better in any case, and essential when you're using NHibernate's proxied classes. Something like this might accomplish what you want:
public class Person
{
public string Name {get;}
}
public class PersonType2 : Person
{
private string something;
public override string Name
{
get
{
return something;
}
set
{
something = value;
}
}
}
public class PersonType2 : Person
{
private string somethingElse;
public override string Name
{
get
{
return somethingElse;
}
set
{
somethingElse = value;
}
}
}
public class Client
{
public int Compare(Client __c1, Client __c2)
{
return __c1.Pers.Name.CompareTo(__c2.Pers.Name);
}
}
Use the is operator instead of GetType():
public class ClientComparer : IComparer<Client>
{
public int Compare(Client __c1, Client __c2)
{
string _name1 = GetName(__c1.Person);
string _name2 = GetName(__c2.Person);
if (_name1 == null)
{
if (_name2 == null)
{
return 0;
}
return -1;
}
if (_name2 == null)
{
return 1;
}
return _name1.CompareTo(_name2);
}
private string GetName(Person person)
{
if (person is Person1)
{
return ((Person1)person).Type1Att;
}
else if (person is Person2)
{
return ((Person2)person).Type2Att;
}
else
{
throw new ArgumentException("Unhandled Person type.");
}
}
}

Categories

Resources