In C#, I can have this:
public class A {
...
private List<int> _items;
public List<int> Items{
get {
if (_items == null){
_items = DAL.FetchFromDB();
}
return _items;
}
}
}
This way, I can intantiate class A, and when I ask for Items
I'm guaranteed to get it without explicitly having to fill the list.
I avoid repeated calls to the database
What would be an equivalent construct for F#?
I'm not sure how to make a type that does this...
I'm not necessarily asking for a mutable list; I'd like to know what a standard form of doing something like this is in F#, as I'm just learning the language.
As ildjarn points out in the above comment, you can use the lazy keyword in an equivalent manner:
type A () =
let items = lazy (DAL.FetchFromDB ())
member this.Items with get () = items.Value
However, the question is whether it's 'idiomatic' F#, or 'good practice' in general?
The Items property isn't referentially transparent (because it isn't deterministic), and Functional Programming tends to have a strong emphasis on referential transparency.
Granted: F# isn't a pure Functional language; it's a Functional First language. Still, it means that to get the most out of it, you should adopt a similar Functional First approach to your design.
The more Functional your own code is, the more value you get out of F#.
The more imperative, implicit, or object-oriented you make your F# code, the less you gain from it.
Thus, it's not always meaningful to attempt to translate C# verbatim to F# code. You can, but will you gain anything from it?
The bottom line is that it's possible to translate your C# to something similar to that in F#, but you should consider whether it's a good idea at all. There's nothing inherently wrong with using the lazy keyword, but the implicitness is something I'd rethink.
This is a one-to-one translation to F#:
type A() =
let mutable _items = null
member this.items
with get() =
if _items = null then _items <- DAL.FetchFromDB()
_items
let a = A()
let x = a.items // db access here
let y = a.items
There are better (and shorter) ways to write equivalent code in F# using objects (see the other answer), but you don't need to create an object at all, you can simply define a function and as others already pointed out you can use the lazy keyword:
let items =
let v = lazy DAL.FetchFromDB()
fun () -> v.Value
let x = items() // db access here
let y = items()
or use the standard lazy value directly, I would prefer this because you are making explicit in the type of items that your value is lazy evaluated instead of hiding it behind a magic object property or function:
let items = lazy DAL.FetchFromDB()
let x = items.Value // db access here
let y = items.Value
So now the type of items is Lazy<'List<'T>> which is always telling you that the value will be lazy computed, apart from that in this case the code is actually shorter.
Related
In the code below, is it possible to dynamically call MyFunction() by changing OtherClass1 with strings a and b?
string a = "OtherClass1", b = "OtherClass2";
myClass = new MyClass();
myClass.OtherClass1.MyFunction();
Something like this:
myClass.a.MyFunction();
Tried to dynamically change it but cant figure out how...
While this is possible to solve this with reflection, it is not something I would recommend, especially not for someone new to coding. You are opting out to all kinds of protections the compiler will give you, and greatly increase the risk of bugs. But if you absolutely want to shoot yourself in the foot you can check out Get property value from string using reflection and How to Invoke Method with parameters.
My recommendation would be to instead make the two classes share an interface, and use an enumerable to select one of them:
public enum MyClasses{
Class1,
Class2
}
public IMyClass GetClass(MyClasses obj){
return obj switch{
MyClasses.Class1 => OtherClass1,
MyClasses.Class2 => OtherClass2,
_ => throw new InvalidOperationException();
}
}
this can then be called with
myClass.GetClass(a).MyFunction();
It would be even better to avoid the problem in the first place, but this pattern can be useful in some cases. You could replace the enum with strings, but that would again increase the chance of mistakes and bugs. It is better to parse the string to an enum in some input layer, that lets you do all the data validation in one place, making the rest of the code more reliable.
I have code like this:
IEnumerable<string?> items = new [] { "test", null, "this" };
var nonNullItems = items.Where(item => item != null); //inferred as IEnumerable<string?>
var lengths = nonNullItems.Select(item => item.Length); //nullability warning here
Console.WriteLine(lengths.Max());
How can I write this code in a convenient way such that:
There is no nullability warning, because the type nonNullItems is inferred as IEnumerable<string>.
I don't need to add unchecked non-nullability assertions like item! (because I want to benefit from the compilers sanity checking, and not rely on me being an error-free coder)
I don't add runtime checked non-nullability assertions (because that's pointless overhead both in code-size and at runtime, and in case of human error that fails later than ideal).
The solution or coding pattern can apply more generally to other sequences of items of nullable-reference type.
I'm aware of this solution, which leverages the flow-sensitive typing in the C# 8.0 compiler, but it's.... not so pretty, mostly because it's so long and noisy:
var notNullItems = items.SelectMany(item =>
item != null ? new[] { item } : Array.Empty<string>())
);
Is there a better alternative?
I think you'll have to help the compiler in either one way or another. Calling .Where() is never safe of returning not-null. Maybe Microsoft could add some logic to determine basic scenarios like yours, but AFAIK that's not the situation right now.
However, you could write a simple extension method like that:
public static class Extension
{
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> o) where T:class
{
return o.Where(x => x != null)!;
}
}
Unfortunately you will have to tell the compiler that you know more about the situation than it does.
One reason would be that the Where method has not been annotated in a way that lets the compiler understand the guarantee for non-nullability, nor is it actually possible to annotate it. There might be a case for having additional heuristics added to the compiler to understand some basic cases, like this one, but currently we do not have it.
As such, one option would be to use the null forgiving operator, colloquially known as the "dammit operator". You touch upon this yourself, however, instead of sprinkling exclamation marks all over the code where you use the collection, you can instead tuck on an additional step on producing the collection which, at least to me, makes it more palatable:
var nonNullItems = items.Where(item => item != null).Select(s => s!);
This will flag nonNullItems as IEnumerable<string> instead of IEnumerable<string?>, and thus be handled correctly in the rest of your code.
I don't know if this answer meets the criteria for your 3rd bullet point, but then your .Where() filter does not either, so...
Replace
var nonNullItems = items.Where(item => item != null)
with
var nonNullItems = items.OfType<string>()
This will yield an inferred type of IEnumerable<string> for nonNullItems, and this technique can be applied to any nullable reference type.
FWIW special support is being considered for C# 10: https://github.com/dotnet/csharplang/issues/3951
I have a class that contains a variable of indeterminate type, which must be overridden at runtime, how can I do this?
Sorry for the disgusting question(
Example:
public class MyClass
{
public e_Type TypeValue;
public (variable of indeterminate type) Value;
}
public enum e_Type
{
string, int, bool, byte
}
At runtime variable TypeValue should determine the type of variable Value
Depending on what you actually mean, you should use either var or dynamic.
The var keyword simply lets the compiler take care of deciding which type you are actually using. If the data you will be assigning is truly dynamic during runtime, it won't do you much good. You should mostly look at var as syntactic sugar (even if it at times can be very, very helpful sugar) - i.e. it just saves you typing.
The dynamic keyword lets you create an object that is truly dynamic, that is you will not get a compiler or runtime error no matter what you try to assign to it. The runtime errors will happen later down the road when you try to call on a property that doesn't exist on it. This is essentially you telling the compiler "Hey, look, just don't give me any fuss about this object, allow me to assign anything to it and call anything on it. If I mess up, it's my problem, not yours."
I think whenever you are thinking about using dynamic you should consider the problem at hand and see if it can be solved in a better way (interfaces, generics etc).
It sounds like you're really after generics:
class Foo<T>
{
public T Value { get; set; };
}
Then you can create instances for different types:
Foo<string> x = new Foo<string>();
x.Value = "fred";
Foo<int> y = new Foo<int>();
y.Value = 10;
This is still fixing the type at compile-time - but when the code using the type is compiled.
var is completely wrong here - var is just used for implicitly typed local variables. In particular, you can't apply it to fields.
It's possible that you want dynamic, but it's not really clear from your question at the moment.
I know that this must be done using the keyword var
Nope, that isn't what var does. There are 3 things that leap to mind that would work:
object; can store anything, but requires reflection to do anything useful
dynamic; a special-case of object, where the compiler performs voodoo such that obj.SomeMethod() (etc) is resolved at runtime
generics, i.e. have the class be SomeType<T>, with the variable typed as T; generic constraints can make this T more usable by declaring features (interfaces) that it must have
var has the purpose of referencing anything, not to declare anything. It's the other way around.
I acomplished this once leveraging the System.Dynamic.ExpandoObject (C# 4 only!), it allows for properties to be added at will without declaring them, and they will be resolved at runtime (it resembles how PHP treats objects and I'm a huge fan of it).
A quick example:
dynamic myObject = new ExpandoObject();
myObject.myProperty = "You can declare properties on-the-fly inside me !";
Console.WriteLine(myObject.myProperty);
In C#, an anonymous type can be as follows:
method doStuff(){
var myVar = new {
a = false,
b = true
}
if (myVar.a)
{
// Do stuff
}
}
However, the following will not compile:
method doStuff(){
var myVar = new {
a = false,
b = true
}
if (myVar.a)
{
myVar.b = true;
}
}
This is because myVar's fields are read-only and cannot be assigned to. It seems wanting to do something like the latter is fairly common; perhaps the best solution I've seen is to just define a struct outside the method.
However, is there really no other way to make the above block work? The reason it bothers me is, myVar is a local variable of this field, so it seems like it should only be referred to inside the method that uses it. Besides, needing to place the struct outside of the method can make the declaration of an object quite far from its use, especially in a long method.
Put in another way, is there an alternative to anonymous types which will allow me to define a "struct" like this (I realize struct exists in C# and must be defined outside of a method) without making it read-only? If no, is there something fundamentally wrong with wanting to do this, and should I be using a different approach?
No, you'll have to create your own class or struct to do this (preferrably a class if you want it to be mutable - mutable structs are horrible).
If you don't care about Equals/ToString/GetHashCode implementations, that's pretty easy:
public class MyClass {
public bool Foo { get; set; }
public bool Bar { get; set; }
}
(I'd still use properties rather than fields, for various reasons.)
Personally I usually find myself wanting an immutable type which I can pass between methods etc - I want a named version of the existing anonymous type feature...
Is there an alternative to anonymous types which will allow me to concisely define a simple "record" type like this without making it read-only?
No. You'll have to make a nominal type.
If no, is there something fundamentally wrong with wanting to do this?
No, it's a reasonable feature that we have considered before.
I note that in Visual Basic, anonymous types are mutable if you want them to be.
The only thing that is really "fundamentally wrong" about a mutable anonymous type is that it would be dangerous to use one as a hash key. We designed anonymous types with the assumptions that (1) you're going to use them as the keys in equijoins in LINQ query comprehensions, and (2) in LINQ-to-Objects and other implementations, joins will be implemented using hash tables. Therefore anonymous types should be useful as hash keys, and mutable hash keys are dangerous.
In Visual Basic, the GetHashCode implementation does not consume any information from mutable fields of anonymous types. Though that is a reasonable compromise, we simply decided that in C# the extra complexity wasn't worth the effort.
In C# 7 we can leverage named tuples to do the trick:
(bool a, bool b) myVar = (false, true);
if (myVar.a)
{
myVar.b = true;
}
You won't be able to get the nice initialization syntax but the ExpandoObject class introduced in .NET 4 would serve as a viable solution.
dynamic eo = new ExpandoObject();
eo.SomeIntValue = 5;
eo.SomeIntValue = 10; // works fine
For the above types of operation, you should define your own mutable STRUCT. Mutable structs may pose a headache for compiler writers like Eric Lippert, and there are some unfortunate limitations in how .net handles them, but nonetheless the semantics of mutable "Plain Old Data" structs (structs in which all fields are public, and the only public functions which write this are constructors, or are called exclusively from constructors) offer far clearer semantics than can be achieved via classes.
For example, consider the following:
struct Foo {
public int bar;
...other stuff;
}
int test(Action<Foo[]> proc1, Action<Foo> proc2)
{
foo myFoos[] = new Foo[100];
proc1(myFoos);
myFoos[4].bar = 9;
proc2(myFoos[4]); // Pass-by-value
return myFoos[4].bar;
}
Assuming there's no unsafe code and that the passed-in delegates can be called and will return in finite time, what will test() return? The fact that Foo is a struct with a public field bar is sufficient to answer the question: it will return 9, regardless of what else appears in the declaration of Foo, and regardless of what functions are passed in proc1 and proc2. If Foo were a class, one would have to examine every single Action<Foo[]> and Action<Foo> that exists, or will ever exist, to know what test() would return. Determining that Foo is a struct with public field bar seems much easier than examining all past and future functions that might get passed in.
Struct methods which modify this are handled particularly poorly in .net, so if one needs to use a method to modify a struct, it's almost certainly better to use one of these patterns:
myStruct = myStruct.ModifiedInSomeFashion(...); // Approach #1
myStructType.ModifyInSomeFashion(ref myStruct, ...); // Approach #2
than the pattern:
myStruct.ModifyInSomeFashion(...);
Provided one uses the above approach to struct-modifying patterns, however, mutable structs have the advantage of allowing code which is both more efficient and easier to read than immutable structs or immutable classes, and is much less trouble-prone than mutable classes. For things which represent an aggregation of values, with no identity outside the values they contain, mutable class types are often the worst possible representation.
I find it really annoying that you can't set anonymous properties as read/write as you can in VB - often I want to return data from a database using EF/LINQ projection, and then do some massaging of the data in c# that can't be done at the database for whatever reason. The easiest way to do this is to iterate over existing anonymous instances and update properties as you go. NOTE this is not so bad now in EF.Core, as you can mix db functions and .net functions in a single query finally.
My go-to workaround is to use reflection and will be frowned upon and down-voted but works; buyer beware if the underlying implementation changes and all your code breaks.
public static class AnonClassHelper {
public static void SetField<T>(object anonClass, string fieldName, T value) {
var field = anonClass.GetType().GetField($"<{fieldName}>i__Field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
field.SetValue(anonClass, value);
}
}
// usage
AnonClassHelper.SetField(inst, nameof(inst.SomeField), newVal);
An alternative I have used when dealing with strings is to make properties of type StringBuilder, then these individual properties will be settable via the StringBuilder methods after you have an instance of your anonymous type.
I know it is really old question but how about replacing whole anonymous
object:
`
if (myVar.a)
{
myVar = new
{ a = false, b = true };
}
`
Background
Currently, if I want to create a new object in C# or Java, I type something similar to the following:
List<int> listOfInts = new List<int>(); //C#
ArrayList<String> data = new ArrayList<String>(); //Java
C# 3.0 sought to improve conciseness by implementing the following compiler trick:
var listofInts = new List<int>();
Question
Since the compiler already knows that I want to create a new object of a certain type (By the fact that I'm instantiating it without assigning it a null reference or assigning a specific method to instantiate it), then why can't I do the following?
//default constructors with no parameters:
List<int> listOfInts = new(); //c#
ArrayList<String> data = new(); //Java
Follow Up Questions:
What are possible pitfalls of this approach. What edge cases could I be missing?
Would there be other ways to shorten instantiation (without using VB6-esque var) and still retain meaning?
NOTE: One of the main benefits I see in a feature like this is clarity. Let say var wasn't limited. To me it is useless, its going to get the assignment from the right, so why bother? New() to me actually shortens it an gives meaning. Its a new() whatever you declared, which to me would be clear and concise.
C# saves in the other end:
var listOfInts = new List<int>();
What edge cases could I be missing?
I briefly discussed this possible C# syntax on my blog in January. See the comments to that post for some reader feedback on the pros and cons of the syntax.
Would there be other ways to shorten instantiation (without using VB6-esque var) and still retain meaning?
Possibly, yes.
"var" in C#, however, is nothing like "variant" in VB6. "var" does not mean the same thing as "object", nor does it introduce dynamic typing or duck typing. It is simply a syntactic sugar for eliminating the redundant stating of the type of the right hand side.
In C# 3 there's already the mirror image for local variables, implicitly typing:
var listOfInts = new List<int>();
This doesn't work for non-local variables though.
In Java, type inference takes into the assignment target into account, so using static imports and cunning libraries such as the Google Java Collections you can write code such as:
List<Integer> integers = newArrayList();
Note that that keeps the variable interface-based while specifying the implementation in the construction side, which is nice.
In the new Java 7 proposals there's a type inference proposal, which will life easier re. generics declarations.
e.g.
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
vs
Map<String, List<String>> anagrams = new HashMap<>();
See here for more information.
In general when using object oriented approaches, you will often create more instances of a more specific type than your variable. Also, it is often a good idea to use a less specific type or an interface. In those cases, this would not make sense.
Think of interfaces:
IList<int> = new(); // What instance should the compiler infer?
Also, from a technical point of view, the signature of an operation does not include its return type, so that this kind of assignment would be completely different from the normal case.
Your version is less readable, sorry.
Code is meant to be read by humans, only incidentally by machines.
I agree that would be a nice feature. A better example would be where even more typing is required:
Dictionary<string, int> myDictionary = new Dictionary<string, int>();
Life would be easier, albeit only slightly, if that could be instantiated as:
Dictionary<string, int> myDictionary = new();
and:
Dictionary<string, int> myDictionary = { {"a",1}, {"b",2} };
C# has:
var listOfInts = new List<int>();
which achieves kind of the same thing.
C# 3.0 has a mechanism to reduce the duplication in typing, but it is done by being vague about the type you're declaring, but explicit in the type you are constructing:
e.g.
var listOfInts = new List<int>();
In C#, there's
var listOfInts = new List<int>();
in C#, theres already something like this namely:
var listOfInts = new List<int>();
In Java this doesn't make too much sense, as you will usually declare variables with the interface type:
List<String> myList = new ArrayList<String>();
It would, however, in most cases make sense to be able to omit the declaration of the generic type without compiler warnings, such as:
List<String> myList = new ArrayList();
But as Java is always very explicit and verbose about everything, this might as well stay the same.
(And why again would anyone code C# or Java without an IDE?)
EDIT:
Oh, there's a proposal for that! Sweet. Thanks, Brian.
Java has
List<String> data = newList(); //Java, where newList() is a helper method to create an ArrayList();
List<String> data = newList("Hello", "World"); // a helper method which takes a T....
Map<String, List<String>> anagrams = newMap(); // Java, where newMap creates a new HashMap();
Code is read from left to right (if your language is not right to left).
That means that
var someTypeWithALongName = new TypeWithALongName<TypeParamOne,TypeParamTwo>();
puts important data to the right part (actual method / type constructor that is used to init variable, from which a reader of the code can infer knowledge about actual var type), which is less convenient to eye, compared to when it is located in the left.
What author suggests however is much better for a left to right reading human - we declare a variable of known type (not some unknown var type)
TypeWithALongName<TypeParamOne,TypeParamTwo> someTypeWithALongName = new();
now important data (actual type that variable will have) is to the left, we can scan code on left side and notice actual types, not a fence of var declarations
var x = ....;
var y = ....;
var z = ....;
var xy = ....;
Code Complete book states that readability is the most important, and I find it hard to disagree with that. Saving 5(or less) seconds and using var instead of real type easily makes code review in future harder, can make code unreadable depending on the right part, and can plant unexpected errors that will be very hard to notice. All with the value of.. saving 5 seconds and not writing a declaring type for variable?
It is now a common knowledge that actual code writing is not taking that much time out of whole time consumed for program creation,especially if it is a product program) ( which usually has debugging, system testing, components integration, design, meetings, etc taking MUCH more time that actual code writing)
On other hand when we type
TypeWithALongName<TypeParamOne,TypeParamTwo> someTypeWithALongName = new();
I find it hard not to interpret that line as anything but calling a default constructor for type and creating an instance of the type.
Also in case of wall of initializations we get actual type names on the beginning of the line, so its easy to scan code from top to bottom and we don't have to move eyes to the end of string to know what actually this concrete var initialization does.( And if you think scanning line to end is a free roll task , first of all its not, and with var its not just scanning, its also checking whether there is a bug in the right part of initialization (for example method with different return type is called or some other types of bugs which var allows))
TypeWithALongName<TypeParamOne,TypeParamTwo> someTypeWithALongName = new();
AnotherTypeWithLongNname someAnotherTypeWithLongNname = new();
List<int> idList = new();
Dictionary<int,string> lookupDict = new ();
I am against var use except for cases it was created for (anonymous types , generally coming from LINQ), and if we were to save up some space in a code I would prefer any code reducing strategies were happening on the right side.
I also believe that using var to declare a variable and assigning it to a return value of some method highly complicates code analysis and often introduces hard to catch bugs, that would have been completely avoided if var wasn't possible for such cases, so if only the constructors code could be shortened to a new() or new(ParamType param) and not some other method like
var x = someTypeLocalIstance.ComputeResults()
readability will only win once more.
I think Microsoft made it this way: a) var xy = new MyClass();
instead of this way: b) MyClass xy = new();
because a) is capable to hold anonymous classes and with b) that would not be possible.