Good Morning All,
I'm trying to use "Contains" to see if an object is within the collection. When I break I can see that the object is indeed part of the collection however "Contains" seems to be returning false indicating the item is not in the collection. Any idea what I'm doing wrong?
if(HttpContext.Current.Session["AutoPayTypes"] != null)
{
var autopays = HttpContext.Current.Session["AutoPayTypes"] as List<PaymentTypeInfo>;
char? coverageProductLine = null;
if(entityProps.ContainsKey("CoverageProductLine"))
{
coverageProductLine = (char?)entityProps["CoverageProductLine"];
}
var paymentTypeInfoRepository = new PaymentTypeInfoRepository();
var payType = paymentTypeInfoRepository.GetPaymentTypeInfo(paymentAdd.PayType,
coverageProductLine);
if (autopays != null && payType != null)
paymentAdd.DaysPaid = autopays.Contains(payType) ? null : paymentAdd.DaysPaid;
}
If the object is not in the collection the "DaysPaid" needs to be null. Any ideas?
***UPDATE
PaymentTypeInfo is a standard LinqToSql generated class. Equals nor GetHashCode has been overridden at this point. Here is it's source.
[Table(Name="dbo.S_OptPaymentType")]
public partial class PaymentTypeInfo
{
private string _PaymentId;
private string _PaymentCode;
private System.Nullable<char> _CoverageType;
private string _ActionCode;
private System.Nullable<char> _PaymentType;
private string _BenAction;
private System.Nullable<char> _BenPremDisFlag;
private string _APNextToLastAct;
private string _APLastAct;
public PaymentTypeInfo()
{
}
[Column(Storage="_PaymentId", DbType="Char(3) NOT NULL", CanBeNull=false)]
public string PaymentId
{
get
{
return this._PaymentId;
}
set
{
if ((this._PaymentId != value))
{
this._PaymentId = value;
}
}
}
[Column(Storage="_PaymentCode", DbType="Char(2) NOT NULL", CanBeNull=false)]
public string PaymentCode
{
get
{
return this._PaymentCode;
}
set
{
if ((this._PaymentCode != value))
{
this._PaymentCode = value;
}
}
}
[Column(Storage="_CoverageType", DbType="Char(1)")]
public System.Nullable<char> CoverageType
{
get
{
return this._CoverageType;
}
set
{
if ((this._CoverageType != value))
{
this._CoverageType = value;
}
}
}
[Column(Storage="_ActionCode", DbType="VarChar(3)")]
public string ActionCode
{
get
{
return this._ActionCode;
}
set
{
if ((this._ActionCode != value))
{
this._ActionCode = value;
}
}
}
[Column(Name="PaymentType", Storage="_PaymentType", DbType="Char(1)")]
public System.Nullable<char> PaymentType
{
get
{
return this._PaymentType;
}
set
{
if ((this._PaymentType != value))
{
this._PaymentType = value;
}
}
}
[Column(Storage="_BenAction", DbType="VarChar(3)")]
public string BenAction
{
get
{
return this._BenAction;
}
set
{
if ((this._BenAction != value))
{
this._BenAction = value;
}
}
}
[Column(Storage="_BenPremDisFlag", DbType="Char(1)")]
public System.Nullable<char> BenPremDisFlag
{
get
{
return this._BenPremDisFlag;
}
set
{
if ((this._BenPremDisFlag != value))
{
this._BenPremDisFlag = value;
}
}
}
[Column(Storage="_APNextToLastAct", DbType="VarChar(3)")]
public string APNextToLastAct
{
get
{
return this._APNextToLastAct;
}
set
{
if ((this._APNextToLastAct != value))
{
this._APNextToLastAct = value;
}
}
}
[Column(Storage="_APLastAct", DbType="VarChar(3)")]
public string APLastAct
{
get
{
return this._APLastAct;
}
set
{
if ((this._APLastAct != value))
{
this._APLastAct = value;
}
}
}
}
Thanks,
~ck in San Diego
EDIT: As Ahmad pointed out, your conditional operator usage is incorrect. However, you don't even need to use the conditional operator here, as one of the branches results in a no-op. Just use this:
if (autopays != null && payType != null && !autopays.Contains(payType))
{
paymentAdd.DaysPaid = null;
}
Original answer
You haven't shown any thing about PaymentTypeInfo - does it override Equals and GetHashCode appropriately? If not, the containment check will be performed using reference identity, and it's very unlikely that the reference in the session is the same as the reference in the repository.
Either make PaymentTypeInfo override Equals and GetHashCode, or pass an appropriate IEqualityComparer<PaymentTypeInfo> into the Contains method.
(As SLaks mentions in the comments, in this case GetHashCode won't actually get called - but you should always override both Equals and GetHashCode or neither of them; if you do override them, you should do so in a consistent manner.)
Unless payType overrides Equals or you specify an IEqualityComparer, Contains will compare by reference.
Your collection probably contains a different instance of the class which is logically equivalent.
It's possible you're running into an equality issue - Contains() uses the IEquatable.Equals method, so you might check to make sure that that's going to return true for separate instances of the PaymentTypeInfo class.
Every post so far has a valid point; depending on the type being used Contains may not suffice. I am addressing a different part of your question though:
If the object is not in the collection
the "DaysPaid" needs to be null. Any
ideas?
How about switching the order of your ternary operator values to match the above statement? Use this:
paymentAdd.DaysPaid = autopays.Contains(payType) ? paymentAdd.DaysPaid : null;
Instead of this:
paymentAdd.DaysPaid = autopays.Contains(payType) ? null : paymentAdd.DaysPaid;
If the statement evaluates to false the 2nd item will be used, so make it null. The structure is:
logic statement ? true : false
Can you post the source of the PaymentType class? I am fairly certain that this type does not provided value-based semantics so the Contains method is forced to resort to using identity equality (which is not giving you the results you want).
If this is the case you may be interested in these articles I wrote on this topic:
All types are not compared equally
All types are not compared equally (part 2)
Related
Assume the following code:
public class CC3
{
private string _field;
private bool _someFlag;
public string Property
{
get { return _field; }
}
public bool SomeFlag
{
get { return _someFlag; }
}
public void SetField()
{
_field = " foo ";
_someFlag = true;
}
public string Method()
{
Contract.Requires(SomeFlag);
return Property.Trim();
}
}
The static checker of Code Contracts complains about the return statement of Method:
Possibly calling a method on a null reference 'this.Property'
What do I have to do to enable the static checker to prove that Property can never be null if SomeFlag is true?
You can give the static analysis a helping hand using Contract.Assume:
public string Method()
{
Contract.Requires(SomeFlag);
Contract.Assume(Property != null);
return Property.Trim();
}
Or actually add the check as a Contract.Requires in its own right. After all, just because you can manually prove it to be true for now, you can't guarantee that will always be the case when the code gets modified. In fact, consider whether SomeFlag being true is actually a requirement at all. Perhaps this is a cleaner solution:
public string Method()
{
Contract.Requires(Property != null);
return Property.Trim();
}
The only way to prove that it is not null is to prove that it is not null. Ideally you could use an invariant if you would convert to auto properties. For this example you could rewrite the property to ensure that null is not a possible result:
public string Property
{
get {
Contract.Ensures(Contract.Result<string>() != null);
return _field ?? String.Empty;
}
}
I have the following getter and setter method:
private Ansprechpartner partner;
public virtual Ansprechpartner Partner
{
get
{
if (partner == null)
{
// something like partner = " ";
}
return partner;
}
set
{
partner = value;
}
}
In the if clause i want to set partner = " ". But of course this isn't working, cause partner is a Typ a the class Ansprechpartner.
Is there a way to do something equivalent, so that partner returns an empty string if (partner == null)?
Please help
is Ansprechpartner your own class?
If it is, than you can return your own defenition of an "empty" Ansprechpartner
return Ansprechpartner.Empty;
and then define the empty property
public class Ansprechpartner
{
public static Ansprechpartner Empty
{
get
{
//generate an empty Ansprechpartner and return it here
}
}
You could override the ToString method from the Ansprechpartner and use a flag attribute like this:
public override ToString()
{
if (FlagAtrribute == null) //Or if it is a string, you could String.IsNullOrEmpty(FlagAtrribute)
{
return "";
}
return FlagAtrribute.ToString();
}
And in your getter just return a new empty instance of the Ansprechpartner class
get
{
if (partner == null)
{
partner = new Ansprechpartner();
}
return partner;
}
And in your code, do something like this:
MyClass.Partner.ToString();
If you change your return type from Ansprechpartner to object you can return anything you would like that derives from object. But I would strongly disagree with taking this approach. If you will want to rethink you're entire approach.
Your property doesn't actually appear to be working with strings, in which case returning a string would be an error.
However, answering your question directly of how to return a string, try something like this:
get
{
if (partner == null)
return String.Empty;
else
return partner;
}
}
Or, better yet:
get
{
return partner ?? String.Empty;
}
you could do something like:
get
{
if (partner == null)
return new Ansprechpartner() {whatever = ""};
else
return partner;
}
In my opinion there is a straightforward way to get exacly what you ask, that is to ensure that it is syntactically correct the folloging:
get
{
if (partner == null)
{
return = "";
}
return partner;
}
The way is to provide an implicict cast operator for the class. Thanks to implicit cast operator, the String.Empty or "" can be automatically casted to Ansprechpartner type, then it is perfectly legal the sysntax you use for the getter.
but what is a implicict cast operator ?
You can even see the question: How do I provide custom cast support for my class? for more detail.
I preferred, however, directly test the code for your class: the code used to successfully test it is the following:
private Ansprechpartner partner;
public virtual Ansprechpartner Partner
{
get
{
// legal assignment thanks to **public static implicit operator Ansprechpartner(string s)**
return partner ?? String.Empty;
}
set
{
partner = value;
}
}
We also try to make the inverse: thanks to public static implicit operator string(Ansprechpartner a) we see that is possible to assign an Empty string to a Ansprechpartner instance variabile
public void test_method()
{
Ansprechpartner s = String.Empty;
}
In the Ansprechpartner class we define cast operators
class Ansprechpartner
{
public static implicit operator Ansprechpartner(string s) {
// put your conversion logic here
// .. i.e: you can simply pass string s to a Ansprechpartner constructor
Ansprechpartner a = new Ansprechpartner();
return a;
}
public static implicit operator string(Ansprechpartner a)
{
if (a == null)
return "";
else
return a.ToString();
}
public Ansprechpartner()
{
}
public override string ToString()
{
return Value;
}
}
That's it, leave a comment if something has not been explained.
I have the code below which I know isn't optimal. I ran the Code Analysis and it gave me the warning
CA1800 : Microsoft.Performance : 'customField', a variable, is cast to type 'DateCustomFieldRef' multiple times in method 'Customer.CustomerToUpdat(SearchResult)'. Cache the result of the 'as' operator or direct cast in order to eliminate the redundant castclass instruction.
and I really don't understand what to do.
CustomFieldRef[] customFields = customer.customFieldList;
for (int f = 3; f < customFields.Length; f++)
{
CustomFieldRef customField = customFields[f];
if (customField is DateCustomFieldRef)
{
DateCustomFieldRef dateField = (DateCustomFieldRef)customField;
if (dateField.internalId != null && dateField.internalId == "created_date")
{
createdDate = dateField.value.ToString();
}
}
if (customField is StringCustomFieldRef)
{
StringCustomFieldRef tradingNameField = (StringCustomFieldRef)customField;
if (businessNameField.internalId != null && businessNameField.internalId == "business_name")
{
businessName = businessNameField.value;
}
}
}
}
Could someone please give me a code example or explain further what it really means?
Thanks in advance.
The problem is in code like:
if (customField is DateCustomFieldRef)
{
DateCustomFieldRef dateField = (DateCustomFieldRef)customField;
These are multiple casts.
Better:
DateCustomFieldRef fieldasDate = customField as DateCustomFieldFRef
if (fieldasDate != null)
{
blablabla using fieldasdate
This avoids the multiple casts.
It means that you're casting (which can be costly) the customField variable multiple times, and that you'd be better of by casting only once.
You can use the as operator to achieve that, since the as operator performs the cast and returns an instance of the desired type, or NULL if the object could not be casted to the desired type.
Like this:
DateCustomFieldRef customField = customFields[f] as DateCustomFieldRef; // the as operator returns null if the casting did not succeed (that is, customFields[f] is not a DatecustomFieldRef instance
if (customField != null)
{
DateCustomFieldRef dateField = customField;
if (dateField.internalId != null && dateField.internalId == "created_date")
{
createdDate = dateField.value.ToString();
}
}
else
{
var stringField = customFields[f] as StringCustomFieldRef;
if (stringField != null )
{
StringCustomFieldRef tradingNameField = stringField;
if (businessNameField.internalId != null && businessNameField.internalId == "business_name")
{
businessName = businessNameField.value;
}
}
}
But, I believe that there probably exists an even better solution (although I do not know your project, nor your code), but wouldn't it be possible to abstract some things away ?
Perhaps you have a CustomField baseclass, and DateCustomFieldRef and StringCustomFieldRef inherit from that Customfield base-class.
If that's the case, you could create a virtual (or maybe even abstract) method in the CustomField base-class, which is overriden in each child-class, which actually returns the value of that field.
Like this:
public class CustomField<T>
{
public string Internalid
{
get;
set;
}
public T Value
{
get;
set;
}
public virtual string GetStringRepresentation()
{
return Value.ToString();
}
}
public class DateCustomField : CustomField<DateTime>
{
public override string GetStringRepresentation()
{
return Value.ToShortDateString();
}
}
Your code can then look much more simple:
foreach( CustomField f in customFields )
{
if( f.InternalId == "created_date" )
{
createdDate = f.GetStringRepresentation();
}
if( f.InternalId == "business_name" )
{
businessName = f.GetStringRepresentation();
}
}
(The code above could be made more simple and clean, but you'll get the drift.)
I have the following code, I want to refactor the duplication out of:
public bool HasBia
{
get
{
if (IsC2User())
{
return true;
}
if(_hasBia == null)
{
_hasBia = _excludes.HasBia;
}
return _hasBia.Value;
}
}
public bool HasTeachAndTest
{
get
{
if (IsC2User())
{
return true;
}
if(_hasTeachAndTest == null)
{
_hasTeachAndTest = _excludes.HasTeachAndTest;
}
return _hasTeachAndTest.Value;
}
}
The bit I am having trouble with is that, _excludes.HasBia and _excludes.HasTeachAndTest are dynamic expressions or dynamic properties that are resolved by TryGetMember of a class that inherits from DynamicObject.
I think I want to do something like this:
public bool HasPermission(bool? value, DynamicExpression expression)
{
if (IsC2User())
{
return true;
}
}
Then I can call it like this:
return HasPermission(_hasBia, _excludes.HasTeachAndTest);
But I am unsure how to invoke the expression when it is passed into the HasPermission method.
Anybody got any ideas?
Perhaps this would work.
public bool HasPermission(ref bool? field, bool defaultValue)
{
if (IsC2User())
{
return true;
}
if (field == null) //lazy loading a bool? overkill? :)
{
field = defaultValue;
}
return field;
}
//usage
public bool HasBia
{
get
{
return HasPermission(ref _hasBia, _excludes.HasBia);
}
}
Or if there are side effects of retrieving the default value
public bool HasPermission(ref bool? field, Func<bool> getDefaultValue)
{
if (IsC2User())
{
return true;
}
if (field == null)
{
field = getDefaultValue();
}
return field;
}
//usage
public bool HasTeachAndTest
{
get
{
return HasPermission(ref _hasTeachAndTest, () => _excludes.HasTeachAndTest);
}
}
I don't think it makes any sense to remove this sort of duplication, consider the additional complexity introduced by any of the possible solutions vs. the simplicity of repeating a pattern at two places.
Perhaps what you are really missing is a concept in your problem domain that you are trying to come by with duplication in your solution domain. Jeff M's solution is fine in regards to a technical implementation, but I'd not use it in this simple case.
How does the == operator really function in C#? If it used to compare objects of class A, will it try to match all of A's properties, or will it look for pointers to the same memory location (or maybe something else)?
Let's create a hypothetical example. I'm writing an application that utilizes the Twitter API, and it has a Tweet class, which has all the properties of a single tweet: text, sender, date&time, source, etc. If I want to compare objects of class Tweet for equivalence, can I just use:
Tweet a, b;
if (a == b)
{
//do something...
}
Will that check for equivalence of all the properties of the Tweet class between a and b?
If not, would the correct approach be to overload the == operator to explicitly check for equivalence of all the fields?
UPDATE: From the first two answers, am I right in assuming:
If the == operator or Equals method is not overloaded for a class, the == operator for the object class is used.
The == operator for the object class checks for equality in memory location.
I have to overload the == operator or the Equals method to accomplish this task.
In the overload, I have to check for equivalence in properties manually, so there is no way to do it semi-automatically, say, in a loop, right?
UPDATE #2: Yuriy made a comment that it is possible to do check for equivalence in properties in the == operator with reflection. How can this be done? Could you give me some sample code? Thanks!
For reference types, the default implementations of both the == operator and the Equals() method will simply check that both objects have the same reference, and are therefore the same instance.
If you want to check the contents of two different objects are equal then you must write the code to do it yourself, one way or another. It would be possible to do with reflection (the MbUnit test framework does something along these lines) but with a heavy performance penalty and a good chance that it wouldn't do quite what you expected anyway, and you should implement == or Equals and GetHashCode by hand.
MSDN has a good example of how to do it:
public override bool Equals(object o)
{
try
{
return (bool) (this == (DBBool) o);
}
catch
{
return false;
}
}
Then you overload the == and !=:
// Equality operator. Returns dbNull if either operand is dbNull,
// otherwise returns dbTrue or dbFalse:
public static DBBool operator ==(DBBool x, DBBool y)
{
if (x.value == 0 || y.value == 0) return dbNull;
return x.value == y.value? dbTrue: dbFalse;
}
// Inequality operator. Returns dbNull if either operand is
// dbNull, otherwise returns dbTrue or dbFalse:
public static DBBool operator !=(DBBool x, DBBool y)
{
if (x.value == 0 || y.value == 0) return dbNull;
return x.value != y.value? dbTrue: dbFalse;
}
And don't forget to overload the GetHash method.
Edit:
I wrote the following quick sample for using reflection in a compare. This would have to be much more comprehensive, I might try doing a blog on it if people want me to:
public class TestEquals
{
private int _x;
public TestEquals(int x)
{
this._x = x;
}
public override bool Equals(object obj)
{
TestEquals te = (TestEquals)obj;
if (te == null) return false;
foreach (var field in typeof(TestEquals)
.GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
{
if (!field.GetValue(this).Equals(field.GetValue(te)))
return false;
}
return true;
}
}
The proper approach is the overload the equals method of the Tweet class in addition to the == operator, as described here.
Will that check for equivalence of all the properties of the Tweet class between a and b?
No
If not, would the correct approach be to overload the == operator to explicitly check for equivalence of all the fields?
You can either overload the == operator, or overload the Equals function.
Edit
#Yuriy gave a good example for compating all the non public variables. Since i also wrote an example, here it is (mine compares properties)
class TwitterItem
{
private string myValue = "default value";
public string Value1
{
get { return myValue; }
set { myValue = value; }
}
public string Value2
{
get { return myValue; }
set { myValue = value; }
}
public string Value3
{
get { return myValue; }
set { myValue = value; }
}
public override bool Equals(object obj)
{
if (base.Equals(obj)) return true;
Type type = typeof(TwitterItem);
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo property in properties)
{
if (false == property.GetValue(this, null).Equals(property.GetValue(obj, null)))
return false;
}
return true;
}
}
You can compare the properties using reflection:
var a = new Entity() { Name = "test", ID = "1" };
var b = new Entity() { Name = "test", ID = "1" };
var c = new Entity() { Name = "test", ID = "2" };
System.Diagnostics.Debug.WriteLine(a.Equals(b));//Returns true
System.Diagnostics.Debug.WriteLine(a.Equals(c));//Returns false
public class Entity
{
public string Name { get; set; }
public string ID { get; set; }
public override bool Equals(object obj)
{
var t = obj.GetType();
foreach (var p in t.GetProperties())
{
if (t.GetProperty(p.Name).GetValue(obj, null) != t.GetProperty(p.Name).GetValue(this, null))
return false;
}
return true;
}
}