Compare Values

S

shapper

Hello,

I am creating a validation class and I defined a few rules. One is the
following:

public static bool Equal<T>(T value, T compare) where T : struct,
IComparable<T> {
return value.CompareTo(compare) == 0;
}

I use this rule to compare two values: strings, ints, doubles, ...

However, when I use:
Rule.Equal("a", "a")

I get the error:
The type 'string' must be a non-nullable value type in order to use it
as parameter 'T' in the generic type or method
'MyApp.Validation.Rule.Equal<T>(T, T)'

What am I doing wrong?

Can't I create a general rule like this?

Thanks,
Miguel
 
N

Nicholas Paldino [.NET/C# MVP]

Miguel,

As Peter says, you can't, because string is a reference type and you
have a constraint on struct. Furthermore, you can't have constraints on
generics which are based on the union (using an OR operation between the
constraints), rather, only an intersection (AND operation on the
constratints).

That being said, you should just use the EqualityComparer<T> class,
calling the static Default property, and then calling Equals on the type
returned, like so:

bool equal = EqualityComparer<string>.Default.Equals(value, compare);

Hope this helps.
 
S

shapper

Miguel,

    As Peter says, you can't, because string is a reference type and you
have a constraint on struct.  Furthermore, you can't have constraints on
generics which are based on the union (using an OR operation between the
constraints), rather, only an intersection (AND operation on the
constratints).

    That being said, you should just use the EqualityComparer<T> class,
calling the static Default property, and then calling Equals on the type
returned, like so:

bool equal = EqualityComparer<string>.Default.Equals(value, compare);

    Hope this helps.

--
          - Nicholas Paldino [.NET/C# MVP]
          - (e-mail address removed)


I am creating a validation class and I defined a few rules. One is the
following:
   public static bool Equal<T>(T value, T compare) where T : struct,
IComparable<T> {
     return value.CompareTo(compare) == 0;
   }
I use this rule to compare two values: strings, ints, doubles, ...
However, when I use:
Rule.Equal("a", "a")
I get the error:
The type 'string' must be a non-nullable value type in order to use it
as parameter 'T' in the generic type or method
'MyApp.Validation.Rule.Equal<T>(T, T)'
What am I doing wrong?
Can't I create a general rule like this?
Thanks,
Miguel

I am a little bit confused about this. I have the following:

public static bool Equal<T>(T value, T compare) where T :
IComparable<T> {
return value.CompareTo(compare) == 0;
}

It compiles. Do you mean I need to create a equal method just for
string?

Sorry, but I am not understanding your suggestion.

Thanks,
Miguel
 
S

shapper

Miguel,

    As Peter says, you can't, because string is a reference type and you
have a constraint on struct.  Furthermore, you can't have constraints on
generics which are based on the union (using an OR operation between the
constraints), rather, only an intersection (AND operation on the
constratints).

    That being said, you should just use the EqualityComparer<T> class,
calling the static Default property, and then calling Equals on the type
returned, like so:

bool equal = EqualityComparer<string>.Default.Equals(value, compare);

    Hope this helps.

--
          - Nicholas Paldino [.NET/C# MVP]
          - (e-mail address removed)


I am creating a validation class and I defined a few rules. One is the
following:
   public static bool Equal<T>(T value, T compare) where T : struct,
IComparable<T> {
     return value.CompareTo(compare) == 0;
   }
I use this rule to compare two values: strings, ints, doubles, ...
However, when I use:
Rule.Equal("a", "a")
I get the error:
The type 'string' must be a non-nullable value type in order to use it
as parameter 'T' in the generic type or method
'MyApp.Validation.Rule.Equal<T>(T, T)'
What am I doing wrong?
Can't I create a general rule like this?
Thanks,
Miguel

You mean this?

public static bool Equal<T>(T value, T compare) where T :
IEqualityComparer<T> {
return EqualityComparer<T>.Default.Equals(value, compare);
} // Equal
 
N

Nicholas Paldino [.NET/C# MVP]

shapper,

Yes, but you don't need the constraint on T. EqualityComparer will work
with any type.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Miguel,

As Peter says, you can't, because string is a reference type and you
have a constraint on struct. Furthermore, you can't have constraints on
generics which are based on the union (using an OR operation between the
constraints), rather, only an intersection (AND operation on the
constratints).

That being said, you should just use the EqualityComparer<T> class,
calling the static Default property, and then calling Equals on the type
returned, like so:

bool equal = EqualityComparer<string>.Default.Equals(value, compare);

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


I am creating a validation class and I defined a few rules. One is the
following:
public static bool Equal<T>(T value, T compare) where T : struct,
IComparable<T> {
return value.CompareTo(compare) == 0;
}
I use this rule to compare two values: strings, ints, doubles, ...
However, when I use:
Rule.Equal("a", "a")
I get the error:
The type 'string' must be a non-nullable value type in order to use it
as parameter 'T' in the generic type or method
'MyApp.Validation.Rule.Equal<T>(T, T)'
What am I doing wrong?
Can't I create a general rule like this?
Thanks,
Miguel

You mean this?

public static bool Equal<T>(T value, T compare) where T :
IEqualityComparer<T> {
return EqualityComparer<T>.Default.Equals(value, compare);
} // Equal
 
N

Nicholas Paldino [.NET/C# MVP]

shapper,

No, you don't. Just removing the struct constraint was enough, but mind
you, this will compile against any type that implements IComparable<T>.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Miguel,

As Peter says, you can't, because string is a reference type and you
have a constraint on struct. Furthermore, you can't have constraints on
generics which are based on the union (using an OR operation between the
constraints), rather, only an intersection (AND operation on the
constratints).

That being said, you should just use the EqualityComparer<T> class,
calling the static Default property, and then calling Equals on the type
returned, like so:

bool equal = EqualityComparer<string>.Default.Equals(value, compare);

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


I am creating a validation class and I defined a few rules. One is the
following:
public static bool Equal<T>(T value, T compare) where T : struct,
IComparable<T> {
return value.CompareTo(compare) == 0;
}
I use this rule to compare two values: strings, ints, doubles, ...
However, when I use:
Rule.Equal("a", "a")
I get the error:
The type 'string' must be a non-nullable value type in order to use it
as parameter 'T' in the generic type or method
'MyApp.Validation.Rule.Equal<T>(T, T)'
What am I doing wrong?
Can't I create a general rule like this?
Thanks,
Miguel

I am a little bit confused about this. I have the following:

public static bool Equal<T>(T value, T compare) where T :
IComparable<T> {
return value.CompareTo(compare) == 0;
}

It compiles. Do you mean I need to create a equal method just for
string?

Sorry, but I am not understanding your suggestion.

Thanks,
Miguel
 
S

shapper

shapper,

    No, you don't.  Just removing the struct constraint was enough,but mind
you, this will compile against any type that implements IComparable<T>.

--
          - Nicholas Paldino [.NET/C# MVP]
          - (e-mail address removed)


As Peter says, you can't, because string is a reference type and you
have a constraint on struct. Furthermore, you can't have constraints on
generics which are based on the union (using an OR operation between the
constraints), rather, only an intersection (AND operation on the
constratints).
That being said, you should just use the EqualityComparer<T> class,
calling the static Default property, and then calling Equals on the type
returned, like so:
bool equal = EqualityComparer<string>.Default.Equals(value, compare);
Hope this helps.

I am a little bit confused about this. I have the following:

    public static bool Equal<T>(T value, T compare) where T :
IComparable<T> {
      return value.CompareTo(compare) == 0;
    }

It compiles. Do you mean I need to create a equal method just for
string?

Sorry, but I am not understanding your suggestion.

Thanks,
Miguel

Ok I understand that since I am checking only if two objects are equal
I should use EqualityComparer:

public static bool Equal<T>(T value, T compare) where T :
IEqualityComparer<T> {
return EqualityComparer<T>.Default.Equals(value, compare);
} // Equal

But with this I get the same problem, I had before, when I use:

Rule.Equal("a", "a")

The type 'string' cannot be used as type parameter 'T' in the generic
type or method 'MyApp.Validation.Rule.Equal<T>(T, T)'. There is no
implicit reference conversion from 'string' to
'System.Collections.Generic.IEqualityComparer<string>'.

But if with it works with IComparable (without struct) why not with
IEqualityComparer?

Could you, please, tell me what is wrong on my code?

Thanks,
Miguel
 
N

Nicholas Paldino [.NET/C# MVP]

shapper,

The compiler is telling you. System.String doesn't implement
IEqualityComparer<string>. It does implement IComparable<T>.

You don't need ANY constraints on your Equals method. Just remove them
and it will work for any type, and it will use the EqualityComparer for that
type.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

shapper,

No, you don't. Just removing the struct constraint was enough, but mind
you, this will compile against any type that implements IComparable<T>.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


As Peter says, you can't, because string is a reference type and you
have a constraint on struct. Furthermore, you can't have constraints on
generics which are based on the union (using an OR operation between the
constraints), rather, only an intersection (AND operation on the
constratints).
That being said, you should just use the EqualityComparer<T> class,
calling the static Default property, and then calling Equals on the type
returned, like so:
bool equal = EqualityComparer<string>.Default.Equals(value, compare);
Hope this helps.

I am a little bit confused about this. I have the following:

public static bool Equal<T>(T value, T compare) where T :
IComparable<T> {
return value.CompareTo(compare) == 0;
}

It compiles. Do you mean I need to create a equal method just for
string?

Sorry, but I am not understanding your suggestion.

Thanks,
Miguel

Ok I understand that since I am checking only if two objects are equal
I should use EqualityComparer:

public static bool Equal<T>(T value, T compare) where T :
IEqualityComparer<T> {
return EqualityComparer<T>.Default.Equals(value, compare);
} // Equal

But with this I get the same problem, I had before, when I use:

Rule.Equal("a", "a")

The type 'string' cannot be used as type parameter 'T' in the generic
type or method 'MyApp.Validation.Rule.Equal<T>(T, T)'. There is no
implicit reference conversion from 'string' to
'System.Collections.Generic.IEqualityComparer<string>'.

But if with it works with IComparable (without struct) why not with
IEqualityComparer?

Could you, please, tell me what is wrong on my code?

Thanks,
Miguel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top