我有一个像这样定义的泛型方法:
public void MyMethod<T>(T myArgument)
Run Code Online (Sandbox Code Playgroud)
我想要做的第一件事是检查myArgument的值是否是该类型的默认值,如下所示:
if (myArgument == default(T))
Run Code Online (Sandbox Code Playgroud)
但是这不能编译,因为我没有保证T将实现==运算符.所以我把代码改为:
if (myArgument.Equals(default(T)))
Run Code Online (Sandbox Code Playgroud)
现在这个编译,但是如果myArgument为null则会失败,这是我正在测试的一部分.我可以像这样添加一个显式的空检查:
if (myArgument == null || myArgument.Equals(default(T)))
Run Code Online (Sandbox Code Playgroud)
现在这让我感到多余.ReSharper甚至建议我将myArgument == null部分更改为myArgument == default(T),这是我开始的地方.有没有更好的方法来解决这个问题?
我需要支持两种引用类型和值类型.
此代码段按预期的int类型工作:
public class Test
{
public int Value
{
get => _Value;
set
{
if (_Value != value)
_Value = value;
}
}
private int _Value;
}
Run Code Online (Sandbox Code Playgroud)
当int被泛型替换时T,编译器抱怨:
运算符'!='不能应用于'T'和'T'类型的操作数
为什么会发生这种情况并且有办法解决它?
这是我正在尝试做的简化版本:
var days = new Dictionary<int, string>();
days.Add(1, "Monday");
days.Add(2, "Tuesday");
...
days.Add(7, "Sunday");
var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));
Run Code Online (Sandbox Code Playgroud)
由于KeyValuePair变量中不存在'xyz',因此FirstOrDefault方法不会返回有效值.我希望能够检查这种情况,但我意识到我无法将结果与"null"进行比较,因为KeyValuePair是一个结构.以下代码无效:
if (day == null) {
System.Diagnotics.Debug.Write("Couldn't find day of week");
}
Run Code Online (Sandbox Code Playgroud)
我们尝试编译代码,Visual Studio会抛出以下错误:
Operator '==' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<int,string>' and '<null>'
Run Code Online (Sandbox Code Playgroud)
如何检查FirstOrDefault是否返回了有效值?
可能重复:
不能将运算符==应用于C#中的泛型类型?
我编写了这样的代码:
public bool IsDataChanged()
{
T value1 = GetValue2;
T value2 = GetValue1();
return (valueInDB != valueFromView);
}
Run Code Online (Sandbox Code Playgroud)
现在该函数没有编译错误" 运算符'!='不能应用于'T'和'T'类型的操作数 ".我该怎么做才能使这个功能起作用?
在.Net 2.5中,我通常可以在值与其类型默认值之间获得相等比较(==)
if (myString == default(string))
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试在默认KeyValuePair和KeyValuePair上运行相等比较时,我得到以下异常
代码示例(来自预扩展方法,proto-lambda静态ListUtilities类:))
public static TKey
FirstKeyOrDefault<TKey, TValue>(Dictionary<TKey, TValue> lookups,
Predicate<KeyValuePair<TKey, TValue>> predicate)
{
KeyValuePair<TKey, TValue> pair = FirstOrDefault(lookups, predicate);
return pair == default(KeyValuePair<TKey, TValue>) ?
default(TKey) : pair.Key;
}
Run Code Online (Sandbox Code Playgroud)
例外:
运算符'=='不能应用于'System.Collections.Generic.KeyValuePair <string,object>'和'System.Collections.Generic.KeyValuePair <string,object>'类型的操作数
是因为,作为结构,KeyValuePair不可为空吗?如果是这种情况,为什么,实际上,默认是为了处理不可为空的类型?
编辑
为了记录,我选择了@Chris Hannon作为选择的答案,因为他给了我正在寻找的东西,最优雅的选择,以及简洁的解释,但我鼓励阅读@Dasuraga以获得非常全面的解释,为什么这是案子
如何在对EF上下文进行查询时结合Find()使用AsNoTracking()以防止跟踪返回的对象.这是我不能做的
_context.Set<Entity>().AsNoTracking().Find(id);
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?我使用EF版本6.
注意:我不想使用SingleOrDefault(),或Where.我只是不能,因为参数Id是通用的,它是一个struct,我不能==在这种情况下应用泛型运算符.
问题的第1部分:在下面的代码中,为什么value == default编译良好,而其他替代方法却没有?
bool MyEqual<T>(T value)
{
T value2 = default;
if (value == value2) // Error: Operator '==' cannot be applied to operands of type 'T' and 'T'
return true;
if (value == default(T)) // Error: Operator '==' cannot be applied to operands of type 'T' and 'T'
return true;
if (value == default) // No error
return true;
return false;
}
Run Code Online (Sandbox Code Playgroud)
问题的第2部分:在下面的代码中,为什么前三幅显示而后三幅false显示true?
bool MyEqual<T>(T value)
{
if (value == default)
return true; …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
class CustomClass
{
public CustomClass(string value)
{ m_value = value; }
public static bool operator ==(CustomClass a, CustomClass b)
{ return a.m_value == b.m_value; }
public static bool operator !=(CustomClass a, CustomClass b)
{ return a.m_value != b.m_value; }
public override bool Equals(object o)
{ return m_value == (o as CustomClass).m_value; }
public override int GetHashCode()
{ return 0; /* not needed */ }
string m_value;
}
class G
{
public static bool enericFunction1<T>(T a1, T a2) where T …Run Code Online (Sandbox Code Playgroud) 我有这个泛型类,它使用Entity Framework 6.x.
public class GenericRepository<TEntity, TId> where TEntity, class, IIdentifyable<TId>
{
public virtual TEntity GetById(TId id)
{
using (var context = new DbContext())
{
var dbSet = context.Set<TEntity>();
var currentItem = dbSet.FirstOrDefault(x => x.Id == id);
return currentItem;
}
}
public virtual bool Exists(TId id)
{
using (var context = new DbContext())
{
var dbSet = context.Set<TEntity>();
var exists = dbSet.Any(x => x.Id == id);
return exists ;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这些接口:
public interface IIdentifyable : IIdentifyable<int>
{
} …Run Code Online (Sandbox Code Playgroud) 我的应用程序定义了几个enum包含该[Flags]属性的s .
我想写一个小的实用程序方法来检查是否为这些中enum的任何一个设置了标志,我想出了以下内容.
protected static bool IsFlagSet<T>(ref T value, ref T flags)
{
return ((value & flags) == flags);
}
Run Code Online (Sandbox Code Playgroud)
但这给了我错误"运算符'&'不能应用于'T'和'T'类型的操作数".
这可以使用吗?