简体   繁体   中英

Change Default Value of a Class

public class MyClass
{
    public string myString;

    public MyClass(string s)
    {
        this.myString = s;
    }
}

In IEnumerable<MyClass> how can I change the default value of FirstOrDefault() method
For example I want to return new MyClass("HelloWorld");

Edit: Is there a way to override default value of a Class?
Like Default Value of MyClass is new MyClass("Default");

You can't directly change it. But you have a few alternatives.

If your sequence contains no null s you can use:

MyClass result = seq.FirstOrDefault() ?? new MyClass("HelloWorld");

Or you can implement your own version which takes a parameter for the default value:

    public static T FirstOrDefault<T>(this IEnumerable<T> source, T defaultValue)
    {
        using (IEnumerator<T> enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
                return enumerator.Current;
            else
                return defaultValue;
        }
    }

    public static T FirstOrDefault<T>(this IEnumerable<T> source, Func<T, bool> predicate, T defaultValue)
    {
        using (IEnumerator<T> enumerator = source.Where(predicate).GetEnumerator())
        {
            if (enumerator.MoveNext())
                return enumerator.Current;
            else
                return defaultValue;
        }
    }

You could also use a different name for your this implementation of FirstOrDefault , but since it doesn't collide with any of the existing overloads, I just used the same name.

https://github.com/CodesInChaos/ChaosUtil/blob/master/Chaos.Util/LinqExtensions.cs

As an equivalent alternative to CodeAsChaos's good answer, you could also do the somewhat shorter:

public static T MyFirstOrDefault<T>(
    this IEnumerable<T> sequence, 
    T myDefault)
{
    foreach(T item in sequence)
        return item;
    return myDefault;
}

public static T MyFirstOrDefault<T>(
    this IEnumerable<T> sequence, 
    Func<T, bool> predicate, 
    T myDefault)
{
    return sequence.Where(predicate).MyFirstOrDefault(myDefault);
}

Why don't just use DefaultIfEmtpy() ?

For instance:

var result = this.MyClasses
    .Where(c => c.SomeCondition)
    .Select(c => c)
    .DefaultIfEmpty(new DefaultClass())
    .First();

You could define an extension method like this:

public static T FirstOrDefault<T>(this IEnumerable<T> source, T defaultValue)
{
    foreach (T x in source)
    {
        return x;
    }
    return defaultValue;
}

I'm going to instead of using generics, just tie it to an enumerable of your class:

public static MyClass FirstOrDefault(this IEnumerable<MyClass> source)
{
    foreach (var x in source)
    {
        return x;
    }
    return new MyClass("hello world"); 
    //OR, could be made a bit nicer by making a static method in your class
    return MyClass.Default();
}

This will do what you want, but only for your class. If this is acceptable, then this is by far the easiest and shortest way of doing it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM