Replies: 9 comments
-
Still not understanding why the existing solution is insufficient. |
Beta Was this translation helpful? Give feedback.
-
Pulling code off Stack Overflow and using that as a shining example of code isn't a good idea in general 😄 The existing solution is based off caller location in source code, so it doesn't work for generics. For example: using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
public class Program
{
public static void Main()
{
Console.WriteLine(GenericThing<int>.GetValue());
Console.WriteLine(GenericThing<short>.GetValue());
Console.WriteLine(GenericThing<bool>.GetValue());
}
public static class GenericThing<T>
{
public static int GetValue()
{
var myVar = StaticLocal<int>.Init(1);
return ++myVar.Value;
}
}
public static class StaticLocal<T>
{
static StaticLocal()
{
dictionary = new Dictionary<int, Dictionary<string, Access>>();
}
public class Access
{
public T Value { get; set; }
public Access(T value)
{
Value = value;
}
}
public static Access Init(T value, [CallerFilePath]string callingFile = "",
[CallerMemberName]string callingMethod = "",
[CallerLineNumber]int lineNumber = -1)
{
var secondKey = callingFile + '.' + callingMethod;
if (!dictionary.ContainsKey(lineNumber))
dictionary.Add(lineNumber, new Dictionary<string, Access>());
if (!dictionary[lineNumber].ContainsKey(secondKey))
dictionary[lineNumber].Add(secondKey, new Access(value));
return dictionary[lineNumber][secondKey];
}
private static Dictionary<int, Dictionary<string, Access>> dictionary;
}
} The output of this program I would think should be I feel like the entire premise for this feature request is off, though. If you had static local variables, you could just do: void Foo()
{
readonly static MyUniqueKeyForThisScope = Guid.NewGuid();
// Hey look, now I have a caller unique ID... and even better, I don't need StaticLocal<T>
} |
Beta Was this translation helpful? Give feedback.
-
This is not about to have an UniqueId... this is about have an uniqueid for the CALLER to a function. C# lacks of "static variables" or "persistent variables" and the implementation NEEDs a real automatic UNIQUEID for the caller. In that scenario, Generics is not a problem. |
Beta Was this translation helpful? Give feedback.
-
Or, alternatively, C# could get static function-local variables... |
Beta Was this translation helpful? Give feedback.
-
Also, if another (there's got to be a proper name for these) callsite-compiler-modified attribute was added like you're suggesting, how would it handle generics? |
Beta Was this translation helpful? Give feedback.
-
Each StaticLocal has his own Dictionary... So...
"a, b, c" goes to different Dictionaries (Different StaticLocal instances with different static dictionary instances) |
Beta Was this translation helpful? Give feedback.
-
Yes, but if you had a look at the code I posted above, you would see why a callsite-generated static identifier doesn't help when you have a generic caller. |
Beta Was this translation helpful? Give feedback.
-
Don't forget the aim of this post... "Static / Persistent local variables". If addition of new caller attributes (I think it is useful fingerprinting caller attributes to long) is not enough change the compiler syntax can be an option:
it is compiled as:
|
Beta Was this translation helpful? Give feedback.
-
@ramoneeza If that was the actual aim, you have a lot of room for improvement in your communications skills. The original issue was named "CallerUniqueIdAttribute". You also said:
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
@ramoneeza commented on Fri Dec 01 2017
The Caller(Members/File/Line) Attributes are very useful in "restricted to class" scenarios like "INotifyChanged" interfaces or exceptions.
But It is not complete in a "per application/library" scenario. (Example "Static variables", "Persistent Variables", etc.)
Stackoverflow has an example of "StaticLocal" implementation showing the problem:
https://stackoverflow.com/questions/2393156/does-c-sharp-support-the-use-of-static-local-variables
A real solution with a "CallerUniqueIdAttribute" simplifies that kind of variables:
I think, it is very simple to the compiler to have a simple counter giving an unique interger value for each [CallerUniqueId] attribute instance when appears.
@CyrusNajmabadi commented on Fri Dec 01 2017
I'm confused. You have a working solution that doesn't need this new attribute. So why would we need to add this new attribute?
@CyrusNajmabadi commented on Fri Dec 01 2017
It's wouldn't be. Furthermore, it wouldn't be sufficient. Take a simple example:
You have this code in your Util.dll library:
Then you have two projects ProjectA and ProjectB that reference that dll. In each of those projects you do:
The compiler will use the uniqueId '0' for each of these since you've only specified "a simple counter". And now ProjectA and ProjectB will both be updating the same variable, violating the desire for this to represent a static local.
@ramoneeza commented on Fri Dec 01 2017
CallerUniqueId must be a "GUID" or a Hash calculated from Module Hash ^ Method.Hash
Implementation of Static Variables ( C++ Style) for Regex, Timers, etc... should be fast enough.
Using several string attributes is not fast.
There are several algorithms and structures (not only static variables) that can make use of this Member Attribute. (And avoid reflection)
@ramoneeza commented on Fri Dec 01 2017
AS easy as make [CallerUniqueId] = [CallerFilePath].Hash ^ [CallerMemberName].Hash ^ [CallerLineNumber] at compiler time.
Or enable [CallerFilePath] and [CallerMemberName] as long type (it implies hash calculation at compile time)
@jcouv commented on Sun Dec 03 2017
I'll go ahead and move to csharplang since this is a language design discussion, not a compiler bug. Thanks
Beta Was this translation helpful? Give feedback.
All reactions